Qt远程对象 - 外部QIO设备

外部QIO设备

Qt远程对象支持多种内置通信通道,例如QTcpServerQTcpSocket。根据所需QUrl或所需名称(适用于QLocalServerQLocalSocket),代码中的侦听和连接是样板代码,并由Qt内部处理。Qt远程对象还支持其他类型的QIODevice,并且QRemoteObjectNode类提供额外的功能,以支持需要自定义代码的情况。

以下是一个构造的TCP/IP示例。更真实的例子将使用SSL连接,这需要配置证书等。

// Create the server and listen outside of QtRO
QTcpServer tcpServer;
tcpServer.listen(QHostAddress(QStringLiteral("127.0.0.1")), 65213);

// Create the host node.  We don't need a hostUrl unless we want to take
// advantage of external schemas (see next example).
QRemoteObjectHost srcNode;

// Make sure any connections are handed to QtRO
QObject::connect(&tcpServer, &QTcpServer::newConnection, &srcNode,
                 [&srcNode, &tcpServer]() {
    srcNode.addHostSideConnection(tcpServer.nextPendingConnection());
});

副本端代码需要手动连接到主机

QRemoteObjectNode repNode;
QTcpSocket *socket = new QTcpSocket(&repNode);
QObject::connect(socket, &QTcpSocket::connected, &repNode,
        [socket, &repNode]() {
    repNode.addClientSideConnection(socket);
});
socket->connectToHost(QHostAddress(QStringLiteral("127.0.0.1")), 65213);

外部模式

如上所示,可以创建QIODevice的每一侧,并调用QRemoteObjectNode::addClientSideConnection(QIODevice *ioDevice)和QRemoteObjectHostBase::addHostSideConnection(QIODevice *ioDevice)。这完全受支持,但要求客户端知道如何建立连接或以某种方式发现该信息。这正是注册设计旨在解决的问题。

Qt远程对象还允许使用注册“外部模式”,这有助于连接设置。在QRemoteObjectHost端,用户必须设置具有所需模式的hostUrl。

// Use standard tcp url for the registry
const QUrl registryUrl = QUrl(QStringLiteral("tcp://127.0.0.1:65212"));
// Use "exttcp" for the "external" interface
const QUrl extUrl = QUrl(QStringLiteral("exttcp://127.0.0.1:65213"));

// Create the server and listen outside of QtRO
QTcpServer tcpServer;
tcpServer.listen(QHostAddress(extUrl.host()), extUrl.port());

// We need a registry for everyone to connect to
QRemoteObjectRegistryHost registry(registryUrl);

// Finally, we create our host node and register "exttcp" as our schema.
// We need the AllowExternalRegistration parameter to prevent the node from
// setting a hostUrlInvalid error.
QRemoteObjectHost srcNode(extUrl, registryUrl, QRemoteObjectHost::AllowExternalRegistration);
// From now on, when we call enableRemoting() from this node, the registry
// will be updated to show the Source object at extUrl.

副本端,QRemoteObjectNode需要在检测到外部模式时注册一个回调。该回调必须是RemoteObjectSchemaHandler

// Use standard tcp url for the registry
const QUrl registryUrl = QUrl(QStringLiteral("tcp://127.0.0.1:65212"));

// This time create the node connected to the registry
QRemoteObjectNode repNode(registryUrl);

// Create the RemoteObjectSchemaHandler callback
QRemoteObjectNode::RemoteObjectSchemaHandler setupTcp = [&repNode](QUrl url) {
    QTcpSocket *socket = new QTcpSocket(&repNode);
    connect(socket, &QTcpSocket::connected,
            [socket, &repNode]() {
        repNode.addClientSideConnection(socket);
    });
    connect(socket, &QSslSocket::errorOccurred,
            [socket](QAbstractSocket::SocketError error) {
        delete socket;
    });
    socket->connectToHost(url.host(), url.port());
};

// Once we call registerExternalSchema, the above method will be called
// whenever the registry sees an object we are interested in on "exttcp"
repNode.registerExternalSchema(QStringLiteral("exttcp"), setupTcp);

© 2024 Qt公司有限责任公司。本文档中的贡献是各自所有者的版权。本提供的文档是根据自由软件基金会按其1.3版GNU自由文档许可证的条款授予的许可。Qt及其标记是芬兰的Qt公司及其在全球其他国家的商标。所有其他商标均为各自所有者的财产。