QHttpServer and WebSockets
-
wrote on 21 Dec 2022, 11:42 last edited by
I try to use the QHttpServer and setup a WebSocket connection for realtime updates (because SSE ist not implemented at the QHttpServer at the moment).
When I start the connection the WebSocket will be closed directly after the newWebSocketConnectionSlot was processed.
Server startup:
m_httpServer.route(m_frontendDir + "/app.js", [this]() { return QHttpServerResponse(m_frontendJS); }); m_httpServer.route("/", [this](const QHttpServerRequest& request) { return getPage(request); }); m_httpServer.route("/data/", [this](const QString& table, const QHttpServerRequest& request) { return getData(request, table); }); connect(&m_httpServer, SIGNAL(newWebSocketConnection()), this, SLOT(newWebSocketConnection()));
WebSocket handling:
void AGVWebServer::newWebSocketConnection() { if (m_httpServer.hasPendingWebSocketConnections() == true) { std::unique_ptr<QWebSocket> up_socket = m_httpServer.nextPendingWebSocketConnection(); m_clients.push_back(std::move(up_socket)); QWebSocket* socket = m_clients[m_clients.size() - 1].get(); connect(socket, &QWebSocket::textMessageReceived, this, &AGVWebServer::processTextMessage); connect(socket, &QWebSocket::disconnected, this, &AGVWebServer::socketDisconnected); } } void AGVWebServer::processTextMessage(QString message) { QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); if (pClient) { pClient->sendTextMessage(message); } } void AGVWebServer::socketDisconnected() { QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); if (pClient) { //TODO m_clients.removeAll(pClient); pClient->deleteLater(); } }
My current workaround is to start a feature task that will never end to keep the connection open:
m_httpServer.route("/notification", [this]() { return QtConcurrent::run([this] () { QEventLoop loop; connect(this, &AGVWebServer::stopWebSockets, &loop, &QEventLoop::quit); loop.exec(); return QHttpServerResponse(""); }); });
How can I use the WebSocket Connection without the QtConcurrent or how to keep the Websocket Connection open?
Thanks
Ronald -
wrote on 21 Dec 2022, 13:33 last edited by
I got it.
I need add a empty route that doesn't return a QHttpServerResponse. If i try to open a WS on a route that returns http data then the connection will be closed. Also if I use a non existing route.
Adding this route will do the magic:
m_httpServer.route("/notification", [](QHttpServerResponder&&) {});
-
I don't see directly why it should be disconnected - apart from the strange (and imho wrong) std::unique_ptr<> stuff it looks fine.
Use a debugger to see why the disconect happens. -
wrote on 21 Dec 2022, 12:29 last edited by
@Mr-Betatester said in QHttpServer and WebSockets:
nextPendingWebSocketConnection
How can I use the WebSocket without the unique_ptr?
nextPendingWebSocketConnection returns a unique_ptr and I have to store it as unique_ptr otherwise it will be delete at function end.https://doc-snapshots.qt.io/qt6-6.4/qabstracthttpserver.html#nextPendingWebSocketConnection
Thanks
-
Sorry, I wasn't aware that they change it this way. Don't know why this was done though. So you have to work with it this way.
-
wrote on 21 Dec 2022, 12:46 last edited by
I can use
QWebSocket* socket = m_httpServer.nextPendingWebSocketConnection().release();
and store a QWebSocket* in my m_clients.
But this doesn't fix the closed connection.Without using the QtConcurrent Chrome close the connection with Code 1006.
-
I can use
QWebSocket* socket = m_httpServer.nextPendingWebSocketConnection().release();
and store a QWebSocket* in my m_clients.
But this doesn't fix the closed connection.Without using the QtConcurrent Chrome close the connection with Code 1006.
@Mr-Betatester said in QHttpServer and WebSockets:
and store a QWebSocket* in my m_clients.
But this doesn't fix the closed connection.As I said it was my fault.
Use a debugger and see why the close happens.
-
wrote on 21 Dec 2022, 13:33 last edited by
I got it.
I need add a empty route that doesn't return a QHttpServerResponse. If i try to open a WS on a route that returns http data then the connection will be closed. Also if I use a non existing route.
Adding this route will do the magic:
m_httpServer.route("/notification", [](QHttpServerResponder&&) {});
-
I got it.
I need add a empty route that doesn't return a QHttpServerResponse. If i try to open a WS on a route that returns http data then the connection will be closed. Also if I use a non existing route.
Adding this route will do the magic:
m_httpServer.route("/notification", [](QHttpServerResponder&&) {});
wrote on 24 May 2023, 14:52 last edited by@Mr-Betatester In Qt 6.5 webSocket with httpserver are not working. It inited but can't send messages.
-
@Mr-Betatester In Qt 6.5 webSocket with httpserver are not working. It inited but can't send messages.
wrote on 24 Jul 2023, 12:30 last edited by@ivanov-ivan At Qt 6.5.0 works code like this:
m_pHttpServer->route("/websocket/<arg>", [this](const QString &arg, const QHttpServerRequest) { qDebug() << __func__ << request << arg; return QFuture<QHttpServerResponse>(); });