本页内容

Qt Remote Objects - 外部 QIODevices

外部 QIODevices

Qt Remote Objects 开箱即支持多种通信通道,例如QTcpServer 和QTcpSocket 这对组合。 只要指定了所需的QUrl (用于tcp),或所需的名称(用于QLocalServer 和QLocalSocket 这对组合),监听和连接所需的代码都是标准模板,由Qt XML在内部处理。Qt Remote Objects 还支持其他类型的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 Remote Objects 此外,还允许在注册表中使用“外部架构”,这有助于连接的建立。在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);

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.