QHttpServer QWebSocket same port - unidirectional websocket
-
wrote on 29 Sept 2024, 04:50 last edited by
I'm attempting to use a QHttpServer for REST services and provide QWebSocket support on the same port as well. REST services work fine. For the WebSocket, a connection is made and I can send data from server to client but I don't receive the data on the server when sent by the client. This is in 6.8rc and I've spent a considerable amount of time working on this with no luck.
Below is the code to make the QWebSockets from the QHttpServer. Strange thing is onSocketDisconnected fires but I cannot capture textMessageRecieved. I've tried replacing the slot with a lambda expression and everything I can think of. On the client side, I can receive messages there and do not get any errors on the write. After multiple writes from the client, the server disconnects me. If I use a QWebSocketServer rather than a QHtttpServer, with nearly identical code (there are some minor differences required), I get bidirectional text messages.
void RestServer::onNewWebSocketConnection () { while(restServer()->hasPendingWebSocketConnections()) { mClients.push_back(restServer()->nextPendingWebSocketConnection()); connect(mClients.back().get(), &QWebSocket::textMessageReceived, this, &RestServer::onTextMessageReceived); connect(mClients.back().get(), &QWebSocket::binaryMessageReceived,this, &RestServer::onBinaryMessageReceived); connect(mClients.back().get(), &QWebSocket::disconnected, this, &RestServer::onSocketDisconnected); connect(mClients.back().get(), &QWebSocket::errorOccurred, this, &RestServer::onWebSocketError); } }
-
wrote on 29 Sept 2024, 09:17 last edited by
Hi
well 6.8 is still in release candidate and thus far from being exempt of any bug. QHttpServer is technical preview. and allowing http and websocket on same port seems to be very new feature in 6.8. So same comment.
did you put any qDebug in that method to log messages to the console to see what happens inside and if everything works as expected ? Is the onNewWebSocketConnection method ever called as expected ?
-
wrote on 29 Sept 2024, 21:07 last edited by
Thank you for the response.
Frankly, I'm leaning towards what you are saying about it potentially being a bug in release candidate. Only because I spent a considerable amount of time, and everything works exactly as expected except I do not receive the signal into my slot. My hope is that this is just a bug that will be fixed because for a specific task I'm working, having the REST and websockets on the same port will be highly beneficial but I wanted to post here to ensure it's not something odd I'm doing or that someone else had an answer. My reason for 6.8 is that it is the next LTS and starting effectively a brand-new development of a large-ish effort, I'd rather be on that version for a while.
To answer your questions, yes, onNewWebSocketConnection is called. I do also receive QWebSocket::disconnected when the client closes before the server, which indicates to me that I am connected to the right thing since the connect is nearly identical, as shown in the code I posted. I have also verified that using that same QWebSocket that I'm storing into mClients can be used to send a text message to the client. I cannot, however, receive anything based on either QWebSocket::textMessageReceived or QWebSocket::binaryMessageReceived signals on the server side, even though I should be connected to them through the code I posed above.
I had originally written the code in 6.7 and at least thought I had everything working but hadn't tested heavily before moving to 6.8. Moving to 6.8 did require several significant changes such as requiring a QTcpServer as QHttpServer no longer listens directly to the connection and requiring an addWebSocketUpgradeVerifier (if you ignore this, onNewWebSocketConnection will never be called as it assumes all websocket connections are denied) which took a little while to figure out. With the significant changes required, clearly things changed under the hood for these classes so I'm hoping it's something that will just be fixed.
Literally, from every indication I have, the code I have works perfectly, with the one exception that websocket communication is one direction. The server can talk to the client, but the client cannot talk to the server via websockets. REST services hosted on the server work perfectly well being accessed from the client side.
I did also break out a QHttpServer and QWebSocketServer seprately. This worked perfectly fine, but only if I used 2 different ports, which is limiting for my specific use case, though I may have to use this as a fallback. Putting them on the same port didn't throw any errors but led to some data losses, which is entirely understandable.
-
Thank you for the response.
Frankly, I'm leaning towards what you are saying about it potentially being a bug in release candidate. Only because I spent a considerable amount of time, and everything works exactly as expected except I do not receive the signal into my slot. My hope is that this is just a bug that will be fixed because for a specific task I'm working, having the REST and websockets on the same port will be highly beneficial but I wanted to post here to ensure it's not something odd I'm doing or that someone else had an answer. My reason for 6.8 is that it is the next LTS and starting effectively a brand-new development of a large-ish effort, I'd rather be on that version for a while.
To answer your questions, yes, onNewWebSocketConnection is called. I do also receive QWebSocket::disconnected when the client closes before the server, which indicates to me that I am connected to the right thing since the connect is nearly identical, as shown in the code I posted. I have also verified that using that same QWebSocket that I'm storing into mClients can be used to send a text message to the client. I cannot, however, receive anything based on either QWebSocket::textMessageReceived or QWebSocket::binaryMessageReceived signals on the server side, even though I should be connected to them through the code I posed above.
I had originally written the code in 6.7 and at least thought I had everything working but hadn't tested heavily before moving to 6.8. Moving to 6.8 did require several significant changes such as requiring a QTcpServer as QHttpServer no longer listens directly to the connection and requiring an addWebSocketUpgradeVerifier (if you ignore this, onNewWebSocketConnection will never be called as it assumes all websocket connections are denied) which took a little while to figure out. With the significant changes required, clearly things changed under the hood for these classes so I'm hoping it's something that will just be fixed.
Literally, from every indication I have, the code I have works perfectly, with the one exception that websocket communication is one direction. The server can talk to the client, but the client cannot talk to the server via websockets. REST services hosted on the server work perfectly well being accessed from the client side.
I did also break out a QHttpServer and QWebSocketServer seprately. This worked perfectly fine, but only if I used 2 different ports, which is limiting for my specific use case, though I may have to use this as a fallback. Putting them on the same port didn't throw any errors but led to some data losses, which is entirely understandable.
wrote on 30 Sept 2024, 00:50 last edited by Pl45m4@ggilman said in QHttpServer QWebSocket same port - unidirectional websocket:
My reason for 6.8 is that it is the next LTS and starting effectively a brand-new development of a large-ish effort, I'd rather be on that version for a while.
FYI:
The LTS only affects commercial license holders.
When using the open-source community Qt license, an LTS version is not better or worse maintained than any other Qt release before or after that.Either you wait couple weeks (IIRC around November) for a stable Qt 6.8 release or you start your project on 6.7
-
wrote on 30 Sept 2024, 02:23 last edited by
Yes, this is for professional software development under the commercial license. It's not registered to the account I'm logged into at the moment, but I do have access to the LTS. I guess with that, I should be able to contact Qt directly under their support as well.
November? October 10 by this source: https://wiki.qt.io/Qt_6.8_Release. Frankly, I need to start building out REST services now, for which my code works fine. Waiting until Oct 10 or even November won't set anything back for my project schedule. Assuming this is just a bug, I was hoping to get confirmation it was known. It's possible the release date could hit with no fix.
Maybe I'll need to put our license to use and contact Qt.
-
wrote on 8 Oct 2024, 13:31 last edited by
I expanded the example, tested it, and only one-way communication, from server to client, works. This bug is likely to have been introduced during the refactoring of the incoming QWebSocket verification in QtHttpServer during development of Qt 6.8.
There are unit tests that should have caught the bug, but they only verifies that new QWebSocket objects are created. They don't check that two-way communication works with the created QWebSockets. -
wrote on 8 Oct 2024, 14:02 last edited by
I have created a bug report here: https://bugreports.qt.io/browse/QTBUG-129798
-
wrote on 9 Oct 2024, 18:08 last edited by
Thank you for the verification. I just updated to the full release of 6.8.0 today and still had the issue so came back here to check this thread. I'm glad to know it's not just something silly I'm doing. It wouldn't be the first time, but I spent enough time on this issue that I was fairly confident it wasn't me.
-
wrote on 21 Oct 2024, 09:43 last edited by
There is now a fix:
https://codereview.qt-project.org/c/qt/qthttpserver/+/597202It is too late for the 6.8.0 release, but it will be in the 6.8.1 release, or you can cherry-pick it.