QtRemoteObjects WebSockets アプリケーション
QtRemoteObjects でQIODevice 以外のトランスポート (QWebSocket) を使う。
この例では、QStandardItemModel
を Web ソケットで共有しています。モデルはwsserver
アプリケーションのウィンドウで編集することができ、その変更はwsclient
アプリケーションのウィンドウに反映されます。
これは、QWebSocket
用に小さなQIODevice 由来のラッパーWebSocketIoDevice
を実装することで可能になります。QtがSSLをサポートしてコンパイルされている場合、SSLが使用されます。
WsServerアプリケーション
wsserver
アプリケーションは2つのカラムを持つQStandardItemModel
を作成し、そこにデータを挿入します。
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); }
そして、ポート8088にバインドされたQWebSocketServer
を起動し、データモデルをホストします。
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);
新しい接続を処理するとき、QtがSSLをサポートしてコンパイルされていれば、SSLが設定されます。その後、WebSocketServer 接続を使用してWebSocketIoDevice
が作成されます。
QObject::connect(&webSockServer, &QWebSocketServer::newConnection, &hostNode, [&hostNode, &webSockServer]{while(autoconn=webSockServer.nextPendingConnection()) {#ifndef QT_NO_SSL // 利用可能な場合は常にセキュアな接続を使用します。 QSslConfigurationsslConf; QFilecertFile(QStringLiteral(":/sslcert/server.crt"));if(!certFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.crt file"); sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}); QFilekeyFile(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(QSslSocketconn->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);autoioDevice= newWebSocketIoDevice(conn); QObject::connect(conn, &QWebSocket::destroyed,ioDevice, &WebSocketIoDevice::deleteLater); hostNode.addHostSideConnection(ioDevice); } });
QStandardItemModel をモデルとして QTreeView を作成します。その後、QTimer::singleShot で複数のタイマが起動され、モデルの修正が行われる。
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();
WsClientアプリケーション
wsclient
アプリケーションはQWebSocketを作成し、それを引数としてWebSocketIoDevice
。
QScopedPointer<QWebSocket> webSocket{new QWebSocket}; WebSocketIoDevice socket(webSocket.data());
QtがSSLをサポートしてコンパイルされている場合、クライアントはSSLで設定されます。
#ifndef QT_NO_SSL // 利用可能な場合は常に安全な接続を使用する。 QSslConfigurationsslConf; QFilecertFile(QStringLiteral(":/sslcert/client.crt"));if(!certFile.open(QIODevice::ReadOnly)) qFatal("Can't open client.crt file"); sslConf.setLocalCertificate(QSslCertificate{certFile.readAll()}); QFilekeyFile(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
次に、QRemoteObjectNode が作成され、WebSocketIoDevice を使用するように設定される。そして、wsserver
に接続する。
QRemoteObjectNode node; node.addClientSideConnection(&socket); node.setHeartbeatInterval(1000); webSocket->open(QStringLiteral("ws://localhost:8088"));
サーバーからのデータを表示するためにQTreeViewが作成されます。モデルはノードから取得され、QTreeView のモデルとして設定され、表示されます。
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();
© 2025 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.