QtRemoteObjects Aplicaciones WebSockets
Usando un transporte no basado enQIODevice(QWebSocket) con QtRemoteObjects.
Este ejemplo comparte un QStandardItemModel a través de un web socket. El modelo puede editarse en la ventana de la aplicación wsserver, y los cambios se propagan a la ventana de la aplicación wsclient.
Esto es posible implementando una pequeña envoltura derivada de QIODevice, WebSocketIoDevice, para QWebSocket. SSL se utiliza si Qt se compila con soporte para ello.

La aplicación WsServer
La aplicación wsserver crea un QStandardItemModel con dos columnas e inserta datos en él.
int main(int argc, char *argv[]) { QLoggingCategory::setFilterRules("qt.remoteobjects.debug=false\n" "qt.remoteobjects.warning=false"); QApplication app(argc, argv); const int modelSize = 100000; QStringList list; QStandardItemModel sourceModel; QStringList hHeaderList; hHeaderList << QStringLiteral("First Column with spacing") << QStringLiteral("Second Column with spacing"); sourceModel.setHorizontalHeaderLabels(hHeaderList); list.reserve(modelSize); for (int i = 0; i < modelSize; ++i) { QStandardItem *firstItem = new QStandardItem(QStringLiteral("FancyTextNumber %1").arg(i)); if (i == 0) firstItem->appendRow(addChild(2, 2)); QStandardItem *secondItem = new QStandardItem(QStringLiteral("FancyRow2TextNumber %1").arg(i)); if (i % 2 == 0) firstItem->setBackground(Qt::red); QList<QStandardItem*> row; row << firstItem << secondItem; sourceModel.invisibleRootItem()->appendRow(row); //sourceModel.appendRow(row); list << QStringLiteral("FancyTextNumber %1").arg(i); }
A continuación, inicia un QWebSocketServer enlazado al puerto 8088, y aloja el modelo de datos.
QWebSocketServer webSockServer{QStringLiteral("WS QtRO"), QWebSocketServer::NonSecureMode}; webSockServer.listen(QHostAddress::Any, 8088); QRemoteObjectHost hostNode; hostNode.setHostUrl(webSockServer.serverAddress().toString(), QRemoteObjectHost::AllowExternalRegistration); hostNode.enableRemoting(&sourceModel, QStringLiteral("RemoteModel"), roles);
Cuando se manejan nuevas conexiones, se configura SSL si Qt está compilado con soporte para ello. Entonces se crea un WebSocketIoDevice usando la conexión WebSocketServer entrante.
QObject::connect(&webSockServer, &QWebSocketServer::newConnection, &hostNode, [&hostNode, &webSockServer]{ while(auto conn = webSockServer.nextPendingConnection()) {#ifndef QT_NO_SSL // Usar siempre conexiones seguras cuando estén disponibles QSslConfiguration sslConf; QFile certFile(QStringLiteral(":/sslcert/server.crt")); if (!certFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.crt file"); sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}); QFile keyFile(QStringLiteral(":/sslcert/server.key")); if (!keyFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.key file"); sslConf.setPrivateKey(QSslKey{keyFile.readAll(), QSsl::Rsa}); sslConf.setPeerVerifyMode(QSslSocket::VerifyPeer); conn->setSslConfiguration(sslConf); QObject::connect(conn, &QWebSocket::sslErrors, conn, &QWebSocket::deleteLater);#endif QObject::connect(conn, &QWebSocket::disconnected, conn, &QWebSocket::deleteLater); QObject::connect(conn, &QWebSocket::errorOccurred, conn, &QWebSocket::deleteLater); auto ioDevice = new WebSocketIoDevice(conn); QObject::connect(conn, &QWebSocket::destroyed, ioDevice, &WebSocketIoDevice::deleteLater); hostNode.addHostSideConnection(ioDevice); } });
Se crea un QTreeView con el QStandardItemModel como modelo. Luego se inician múltiples temporizadores con QTimer::singleShot para realizar más modificaciones al modelo.
QTreeView view; view.setWindowTitle(QStringLiteral("SourceView")); view.setModel(&sourceModel); view.show(); TimerHandler handler; handler.model = &sourceModel; QTimer::singleShot(5000, &handler, &TimerHandler::changeData); QTimer::singleShot(10000, &handler, &TimerHandler::insertData); QTimer::singleShot(11000, &handler, &TimerHandler::changeFlags); QTimer::singleShot(12000, &handler, &TimerHandler::removeData); QTimer::singleShot(13000, &handler, &TimerHandler::moveData); return app.exec();
La Aplicación WsClient
La aplicación wsclient crea un QWebSocket y un WebSocketIoDevice tomándolo como argumento.
QScopedPointer<QWebSocket> webSocket{new QWebSocket}; WebSocketIoDevice socket(webSocket.data());
Si Qt se compila con soporte para SSL, el cliente se configura con él.
#ifndef QT_NO_SSL // Usar siempre conexiones seguras cuando estén disponibles QSslConfiguration sslConf; QFile certFile(QStringLiteral(":/sslcert/client.crt")); if (!certFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.crt file"); sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}); QFile keyFile(QStringLiteral(":/sslcert/client.key")); if (!keyFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.key file"); sslConf.setPrivateKey(QSslKey{keyFile.readAll(), QSsl::Rsa}); sslConf.setPeerVerifyMode(QSslSocket::VerifyPeer); webSocket->setSslConfiguration(sslConf);#endif
Entonces se crea un QRemoteObjectNode, y se configura para usar el WebSocketIoDevice. Luego se conecta a wsserver.
QRemoteObjectNode node; node.addClientSideConnection(&socket); node.setHeartbeatInterval(1000); webSocket->open(QStringLiteral("ws://localhost:8088"));
Se crea un QTreeView para mostrar los datos del servidor. El modelo se adquiere del nodo, y luego se establece como el modelo del QTreeView, que luego se muestra.
QTreeView view; view.setWindowTitle(QStringLiteral("RemoteView")); view.resize(640,480); QScopedPointer<QAbstractItemModelReplica> model(node.acquireModel(QStringLiteral("RemoteModel"))); view.setModel(model.data()); view.show(); return app.exec();
© 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.