summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorØystein Heskestad <oystein.heskestad@qt.io>2023-05-23 15:45:53 +0200
committerØystein Heskestad <oystein.heskestad@qt.io>2023-06-06 09:35:55 +0200
commit5586e24e1e8330b55dd738a4eac000faafcf22c9 (patch)
treee6534914e820c09f1cdc03c28a1721bae5b054b0 /examples
parent743de69538696ea14e299c32056d40851bb9fdcd (diff)
Revamp WebSockets example
Fix a warning, expand the documentation, and add a picture to it. Task-number: QTBUG-112850 Pick-to: 6.5 6.6 Change-Id: I203392a95bef206fecc2777d060e215d95235296 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/remoteobjects/websockets/doc/src/websocket.qdoc59
-rw-r--r--examples/remoteobjects/websockets/wsclient/main.cpp12
-rw-r--r--examples/remoteobjects/websockets/wsserver/main.cpp10
3 files changed, 76 insertions, 5 deletions
diff --git a/examples/remoteobjects/websockets/doc/src/websocket.qdoc b/examples/remoteobjects/websockets/doc/src/websocket.qdoc
index a1a3c91..a18a9fb 100644
--- a/examples/remoteobjects/websockets/doc/src/websocket.qdoc
+++ b/examples/remoteobjects/websockets/doc/src/websocket.qdoc
@@ -3,10 +3,65 @@
/*!
\example websockets
- \title QtRemoteObjects WebSockets Example
+ \title QtRemoteObjects WebSockets Applications
\brief Using a non-QIODevice-based transport (QWebSocket) with QtRemoteObjects.
+ \examplecategory {Input/Output}
+ \meta tag {rpc,network,websockets}
\ingroup qtremoteobjects-examples
- This is achieved by implementing a small QIODevice-derived wrapper for QWebSocket.
+ This example shares a \c QStandardItemModel over a web socket. The model
+ can be edited in the window of the \c wsserver application, and the
+ changes are propagated to the window of the \c wsclient application.
+ This is made possible by implementing a small QIODevice-derived wrapper,
+ \c WebSocketIoDevice, for \c QWebSocket. SSL is used if Qt is compiled
+ with support for it.
+
+ \image StandardItemTableWindow.webp
+
+ \section1 The WsServer Application
+
+ The \c wsserver application creates a \c QStandardItemModel with two
+ columns and inserts data into it.
+
+ \snippet websockets/wsserver/main.cpp 0
+
+ It then starts a \c QWebSocketServer bound to port 8088, and hosts the
+ data model.
+
+ \snippet websockets/wsserver/main.cpp 1
+
+ When handling new connections, SSL is configured if Qt is compiled
+ with support for it. Then a \c WebSocketIoDevice is created using the
+ incoming WebSocketServer connection.
+
+ \snippet websockets/wsserver/main.cpp 2
+
+ A QTreeView is created with the QStandardItemModel as model.
+ Then multiple timers are started with QTimer::singleShot to perform
+ more modifications to the model.
+
+ \snippet websockets/wsserver/main.cpp 3
+
+ \section1 The WsClient Application
+
+ The \c wsclient application creates a QWebSocket and a
+ \c WebSocketIoDevice taking it as an argument.
+
+ \snippet websockets/wsclient/main.cpp 0
+
+ If Qt is compiled with support for SSL, the client is configured with it.
+
+ \snippet websockets/wsclient/main.cpp 1
+
+ Then a QRemoteObjectNode is created, and setup to use the
+ WebSocketIoDevice. Then it connects to \c wsserver.
+
+ \snippet websockets/wsclient/main.cpp 2
+
+ A QTreeView is created to display the data from the server. The model is
+ acquired from the node, and it is then set as the model of the
+ QTreeView, which is then shown.
+
+ \snippet websockets/wsclient/main.cpp 3
*/
diff --git a/examples/remoteobjects/websockets/wsclient/main.cpp b/examples/remoteobjects/websockets/wsclient/main.cpp
index 0d6387b..c025497 100644
--- a/examples/remoteobjects/websockets/wsclient/main.cpp
+++ b/examples/remoteobjects/websockets/wsclient/main.cpp
@@ -24,10 +24,12 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
-
-
+ //! [0]
QScopedPointer<QWebSocket> webSocket{new QWebSocket};
WebSocketIoDevice socket(webSocket.data());
+//! [0]
+
+//! [1]
#ifndef QT_NO_SSL
// Always use secure connections when available
QSslConfiguration sslConf;
@@ -44,11 +46,16 @@ int main(int argc, char **argv)
sslConf.setPeerVerifyMode(QSslSocket::VerifyPeer);
webSocket->setSslConfiguration(sslConf);
#endif
+ //! [1]
+
+ //! [2]
QRemoteObjectNode node;
node.addClientSideConnection(&socket);
node.setHeartbeatInterval(1000);
webSocket->open(QStringLiteral("ws://localhost:8088"));
+ //! [2]
+ //! [3]
QTreeView view;
view.setWindowTitle(QStringLiteral("RemoteView"));
view.resize(640,480);
@@ -57,4 +64,5 @@ int main(int argc, char **argv)
view.show();
return app.exec();
+ //! [3]
}
diff --git a/examples/remoteobjects/websockets/wsserver/main.cpp b/examples/remoteobjects/websockets/wsserver/main.cpp
index 4c0dd67..39a8cf6 100644
--- a/examples/remoteobjects/websockets/wsserver/main.cpp
+++ b/examples/remoteobjects/websockets/wsserver/main.cpp
@@ -70,6 +70,7 @@ QList<QStandardItem*> addChild(int numChildren, int nestingLevel)
return result;
}
+//! [0]
int main(int argc, char *argv[])
{
QLoggingCategory::setFilterRules("qt.remoteobjects.debug=false\n"
@@ -96,6 +97,7 @@ int main(int argc, char *argv[])
//sourceModel.appendRow(row);
list << QStringLiteral("FancyTextNumber %1").arg(i);
}
+ //! [0]
// Needed by QMLModelViewClient
QHash<int,QByteArray> roleNames = {
@@ -107,6 +109,7 @@ int main(int argc, char *argv[])
QList<int> roles;
roles << Qt::DisplayRole << Qt::BackgroundRole;
+ //! [1]
QWebSocketServer webSockServer{QStringLiteral("WS QtRO"), QWebSocketServer::NonSecureMode};
webSockServer.listen(QHostAddress::Any, 8088);
@@ -114,7 +117,9 @@ int main(int argc, char *argv[])
hostNode.setHostUrl(webSockServer.serverAddress().toString(), QRemoteObjectHost::AllowExternalRegistration);
hostNode.enableRemoting(&sourceModel, QStringLiteral("RemoteModel"), roles);
+ //! [1]
+ //! [2]
QObject::connect(&webSockServer, &QWebSocketServer::newConnection, &hostNode, [&hostNode, &webSockServer]{
while (auto conn = webSockServer.nextPendingConnection()) {
#ifndef QT_NO_SSL
@@ -135,13 +140,15 @@ int main(int argc, char *argv[])
QObject::connect(conn, &QWebSocket::sslErrors, conn, &QWebSocket::deleteLater);
#endif
QObject::connect(conn, &QWebSocket::disconnected, conn, &QWebSocket::deleteLater);
- QObject::connect(conn, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), 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);
}
});
+ //! [2]
+ //! [3]
QTreeView view;
view.setWindowTitle(QStringLiteral("SourceView"));
view.setModel(&sourceModel);
@@ -155,6 +162,7 @@ int main(int argc, char *argv[])
QTimer::singleShot(13000, &handler, &TimerHandler::moveData);
return app.exec();
+ //! [3]
}
#include "main.moc"