Multithreaded qwebsocket - competing server
I do have a problem with a multithreaded websocket server:
So far I have successfully implemented a single threaded websocket server using the qwebsocketserver class. Pretty much following the qt example for the chat server.
Processing my specific server side business logic can take quite some time and therefore I would like to spawn separate threads for incoming requests to stay responsive to my clients.
The QWebSocketServer documentation for "QWebSocketServer::nextPendingConnection()" states: "The returned QWebSocket object cannot be used from another thread."
How am I supposed to implement a competing web socket server?
I appreciate any inputs
Thanks a lot in advance
-i guess you can just keep a single socket and for all data you receive, and then spawn a new thread for each incoming data and send it the data; then, when the thread completes its job, make it send a signal to the main thread with the result, and from the main thread send out the result on the socket.-
scratch the above, it's nonsense, you need multiple sockets, sorry
I have not used the QWebSocketServer so I am not familiar with it. However, I have used QTcpSocket and QTcpServer classes which I imagine are similar in structure. If not, then you could consider using them because they are capable of the tasks you seem to be wanting.
Most examples I found when researching how to do this followed a basic pattern: generally speaking, they accomplished what you seem to be doing by having the server (listener) itself running in the main thread. Then, when an incoming connection comes, a new thread is created for the incoming connection so that all communication is done separately from the server's thread. That way it can continue to listen and repeat this thread spawning for each new connection that comes in.
There are a few different ways to do this and examples do exist around the web. If I remember correctly, some move the socket manually using a command that I don't recall (because I used a different method). Some use the socket's identifier (an int ptr or an int) to actually pull (or reproduce) the socket in the new thread. The example I loosely followed used this latter method and can be found "here":http://www.bogotobogo.com/Qt/Qt5_QTcpServer_Multithreaded_Client_Server.php. I know this doesn't use the same classes but the basic idea is probably reproducible using the classes you are currently using (since most of these networking classes are based on the same abstract/base classes).
Thank you for your response.
I’d prefer using websockets over standard tcp sockets (due to easier firewall configuration and the possibility of bi-directional communication)
Of course I tried spawning a thread on each new connection and have the QWebSocket live in this separate thread. But this does not seem to work:
I am instantiating a new QThread-derivitive object in my "newConnection" slot.
In this separate thread (run-message) I am calling nextPendingConnection to get a new QWebSocket, which I am moving to my new thread ("moveToThread"). Then I am hooking up all the websocket’s relevant signals to my corresponding slots within this thread.
Inside my textMessageReceived(QString) slot I am calling QWebSocket::sendTextMessage(“blabla”) to send some response back to the client.
Now all the QWebSocket signals (ex. textMessageReceived) are triggering the right slot in my new thread. The only problem is, that the response I am sending does not find its way back to the client anymore. (This works in the single threaded scenario).
Side note: When I am calling QObject::moveToThread(myThread) I get the following warning:
“QSocketNotifier: socket notifiers cannot be enabled from another thread”
Since the documentation says: “Note: The returned QWebSocket object cannot be used from another thread” I wonder if the common approach of spawning new threads on incoming connections is even possible with the current QT QWebSockets implementation?
I am not sure about the answer to your final question since I have not used the QWebSocket version. However I am also not sure why you feel that standard tcp sockets are easier than web sockets. Tcp sockets are also bidirectional and in my experience, nowadays you don't have to worry about your firewall. The first time I ran my app, the standard windows firewall detected the attempt and asked me if I wanted to allow the app to use the socket. It automatically configured the port and application for later use.
After doing a quick read of the purpose of the WebSocket protocol, I think the only major difference is that communication can go both ways at the same time. It also doesn't look like you can transfer the socket to a new thread by using the socket id. Too bad because that makes Tcp sockets easier to bypass the having to transfer the socket manually to another thread.