-
Hi, usockets, uWebSockets are very helpful and easy to use libraries. Thank you. I am trying to get handle on using uWebSockets in a multi-thread server environment Please see the sample code below. The server runs and accepts ws connections from clients. I connected 4 browser clients (for testing) successfully.
Is there any way to publish to all clients in a multi-threaded server? Could you please advice?
|
Beta Was this translation helpful? Give feedback.
Replies: 10 comments 7 replies
-
This should be added to the user manual under Scaling up, Every thread has its own Loop, and uWS::Loop::get() returns the Loop for current thread. Loop::defer(function) is the only thread-safe function here; you use it to defer the calling of a function to the thread that runs the Loop. Use this to signal every Loop that it should publish some message. |
Beta Was this translation helpful? Give feedback.
-
Thank you, Alex Hultman |
Beta Was this translation helpful? Give feedback.
-
Thank you, Alex Hultman. Could you please provide an example to use Loop::defer(function) in this context in the FAQ / user manual of Scaling up? |
Beta Was this translation helpful? Give feedback.
-
Hi, I have created a sample program that may be added in the FAQ / Scaling up manual. I am stuck at how to trigger Loop::defer() that call publish(). Could you please advice?
|
Beta Was this translation helpful? Give feedback.
-
You don't need to involve signals. I meant "signal" in an abstract sense. Loop::defer is really all you need |
Beta Was this translation helpful? Give feedback.
-
Thank you, Alex Hultman. Yes, I tried without SIGUSR1 'signals'. I am able to call it Loop::defer from .message handler. I am not able to follow how to publish from / within the lambda of w.loop_->defer({ }); I got the mechanism of Loop::defer . It adds the callback (the lambda) and wakesup the loop. So, the lambda shall have the socket context and call publish on it. I got stuck there. Sorry to bother you - I will prepare the FAQ / Scaling up manual to contribute to the project.
|
Beta Was this translation helpful? Give feedback.
-
Yes it becomes a bit tricky since you need to capture the uWS::App inside a lambda that constructs the app itself. You need to capture the address of the stack allocated app (or any such solution):
Or just put the app in global namespace with thread_local scope |
Beta Was this translation helpful? Give feedback.
-
Thank you, Alex Hultman. I am able to get uWS::App to the Loop::defer lambda function. Thank you for your guidance. I will prepare a note on this for FAQ / Scaling up and send it to you.
Best Regards |
Beta Was this translation helpful? Give feedback.
-
Thank you, Alex Hultman. Closing the issue. Best Regards |
Beta Was this translation helpful? Give feedback.
-
Scaling upOne event-loop per thread, isolated and without shared data. That's the design here. Just like Node.js, but instead of per-process, it's per thread (well, obviously you can do it per-process also). If you want to, you can simply take the previous example, put it inside of a few std::thread and listen to separate ports, or share the same port (works on Linux). More features like these will probably come, such as master/slave set-ups but it really isn't that hard to understand the concept - keep things isolated and spawn multiple instances of whatever code you have. Recent Node.js versions may scale using multiple threads, via the new Worker threads support. Scaling using that feature is identical to scaling using multiple threads in C++. Sample CodeThis sample code demonstrates uWS::Loop per thread and signaling each thread - for example broadcasting a message to all the clients serving in all the threads. It demonstrates using thread safe uWS::Loop::defer (function).
|
Beta Was this translation helpful? Give feedback.
This should be added to the user manual under Scaling up,
Every thread has its own Loop, and uWS::Loop::get() returns the Loop for current thread.
Loop::defer(function) is the only thread-safe function here; you use it to defer the calling of a function to the thread that runs the Loop. Use this to signal every Loop that it should publish some message.