Writing a scalable tcp socket server i.e not 1 thread per connection
-
I'm in the process of writing a tcp socket server and want to make it a scalable solution. By scalable I mean I don't want 1 thread per connection but instead use a thread from a threadpool to service a request as it comes in, then give the thread back to the pool even if the connection is still open.
I originally thought that the right way of doing this would be to have a QTcpServer listening on the main thread , when a tcp request comes in the QTcpServer gives me a QTcpSocket, when the readyRead signal on the socket is fired I pass the socketdescriptor to a QRunnable with a run method where a local QTcpSocket has it's descriptor set and a readall can be executed. The Qrunnable is kicked off by passing it to the global Qthreadpool for execution in another thread.
What I'm finding with this design is that the readyRead signals fires but the socket in qrunnable::run method receives no data.
Any ideas on how to achieve this would be very much appreciated. Here's my "question ":http://stackoverflow.com/questions/23812483/how-to-pass-a-qtcpsocket-to-a-qrunnable-in-qt-5-2 on stackoverflow. I've posted an answer to my own question but I know it's the wrong way of doing it. I'll correct that when I find a solution.
-
I prefear to use one thread for each connection but, using bluetooth libraries, is not possible to use threads.
Using events all works well with ReadyRead and ReadAll methods.
Are you sure you haven't made mistakes in you code? -
Thanks for you reply mrdebug.
Because I anticipate having a large number of concurrent incoming connections to service, 1 thread per connection would not be feasible, that's why I was looking at using QThreadPool and QRunnable.
Just as a sanity check I used a simpler method which uses ReadyRead and ReadAll in the main thread and it works fine, it's just when I start to use QThreadPool and QRunnable that things stop working.
I think the mistake is in my approach rather than the code itself.
The problem may be that the main thread is creating a QTcpSocket and it's descriptor is being passed into a different QTcpSocket in another thread. Each instance of the QTcpSocket MAY (although I'm not sure) have it's own internal buffer and the socket in the main threads buffer is being filled whilst the socket in other thread isn't, so when I readaAll on the socket in the thread I get nothing back.
-
Can someone comment as to why I'm getting little feedback here? Is there a way I can change/move the post so I can get feedback? Does my question make sense or does it need more information?
-
Hi,
Feedback is dependent on the timezone/knowledge of people here, it's not uncommon to wait 24 to 48 hours for an answer. Your question is clear but your use case is not what most users here have experience with. You can also go to the interest mailing list, you'll find Qt's developers/maintainers (this forum is more user oriented)
-
Thanks for the feedback SGaist , I'm new here and also to Qt so I appreciate you pointing me in the right direction. I'll target the developers/maintainers as you suggested.
Regards
Rich -
Probably this tutorial could be useful for you:
"Advanced Asynchronous QTcpServer with QThreadPool":http://voidrealms.com/index.php?r=tutorial/view&id=256 -
Thanks qxoz, I've been through voidrealms tutorials, an excellent resource. I learned socket server stuff from that tutorial amongst others he's written but I don't think his example is quite what I'm looking for. I think to be scalable reading data from the socket needs to get a thread do a readall then release the thread and writing to the thread needs to do the same otherwise you end up with 1 thread being held onto whilst the connection is open and it turns into a 1 thread per connection scenario which isn't scalable.
I am a noob at Qt so I invite anyone to correct me if my explanations show misunderstandings of any kind.