Before going to production, we want to make sure that this is an "as expected behavior".
I have conducted an experiment by laucnhing 4 child processes using a PM2 cluster (I have 4 cores on my machine). Which means there were 4 websocket processes running...
Then on the client I created multiple sockets, and sent many messages to the server. One thing I didn't expect was that Node was able to figure out what child process the socket belonged to, meaning that every message sent by the client was console logged by the correct child process.
It seems like the main worker in the cluster keeps track of what sockets belong where.
So is this managed by Nodejs internally by the "cluster" module?
Also is this ok to use in production?
P.S. for websockets we use "ws" module for Nodejs
I aksed the same question on github. And got an answer...
Also please look into using ClusterWs - it's awesome!
https://github.com/ClusterWS/ClusterWS/issues/143
Related
I have a node application that uses Socket.IO for the messaging.
And I run it using
node --expose_gc /path/to/app.js
Now, when I check on the htop utility, I noticed that instead of 1, I am getting multiple processes of the same command.
Can someone, in noob terms, explain to me why and what is going on here? I'm also worried that it may consume unexpected memory/cpu usage too.
socket.io does not fork or spawn any child processes.
usually sub processes that run node.js are spawned via cluster module but socket.io does no such thing.
it just adds a handler on top of a http server.
socket.io is just a library that hooks into a web server and listens for certain incoming requests (those requests that initiate a webSocket/socket.io connection). Once a socket.io connection is initiated, it just uses normal socket programming to send/receive messages.
It does not start up any additional processes by itself.
Your multiple processes are either because you accidentally started your own app multiple times without shutting it down or there is something else in your app that is starting up multiple processes. socket.io does not do that.
Hello i am trying to make a multiplayer game with nodejs and socket.io.
I am using multi process socket.io with cluster and socket.io-redis. It works well if you want to broadcast messages, emit etc.
But if i want to add some complexity in my code problems start to appear. I want my game to have a matchmaking function.
Assume this scenario:
Server find 2 users that want to play and start a game.
Users are on different processes on the same machine.
The problem is that a client can communicate with only one process the one that firstly got in.
So there are 3 possible solutions as I see it:
Matchmake with users that is on the same proccess --- Not good.
Create an ipc method between processes so the one with the target client can broadcast client's answer to the correct process --- Too complex and not sure if solves everything.
Change client's socket.io process to a new one without the user notice it --- Not sure if this is even possible.
Is there something i am missing here? Is there any other solution that i can't think?
Any help appreciated!
With socket.io-redis users can communicate even if they are in different servers/processes, this is why it exists.
In the parent process, I have started the tiny-lr(livereload) server, followed by spawing a child process which looks for changes to the css files. how to pass on the livereload server to the child process or is it possible to query for the livereload server that is currently running in the child process so that I don't create it again getting an already in use error for the port.
the same case with node http server. can I know if the server is already running and use that instead of creating new one.
is it possible to query for the livereload - it is possible and may be implemented in more than one way.
Use stdout/stdin to communicate with the child process. For detailed description look HERE. Basically you can send messages from one process to the other and reply to them.
Use http.request to check if the port is in use.
You can use a file: the process with the server keeps the file open in the write mode - the content of the file stores the port on which the server runs (if needed).
You can use sockets for inter-process communication, as well.
Basically, none of the above guarantees 100% confidentiality, so you have to try/catch for errors anyway: the server may die just after your check, but before you wanted to do something with it.
how to pass on the livereload server to the child process - if you mean sharing an object between different process that it is for sure out of question; if you mean changing the ownership of the object that I am some 99,99% sure it is not possible neither.
What is the problem with having just one process responsible for running the server? And why not to use, let say, forever to take care of running and restarting the server, if needed?
This is more of a design question rather than implementation but I am kind of wondering if I can design something like this. I have an interactive app (similar to python shell). I want to host a server (lets say using either node.js http server or socket.io since I am not sure which one would be better) which would spawn a new child_process for every client that connects to it and maintains a different context for that particular client. I am a complete noob in terms of node.js or socket.io. The max I have managed is to have one child process on a socket.io server and connect the client to it.
So the question is, would this work ? If not is there any other way in node to get it to work or am I better off with a local server.
Thanks
Node.js - is single process web platform. Using clustering (child_process), you will create independent execution of same application with separate thread.
Each thread cost memory, and this is generally why most of traditional systems is not much scalable as will require thread per client. For node it will be extremely inefficient from hardware resources point of view.
Node is event based, and you dont need to worry much about scope as far as your application logic does not exploit it.
Count of workers is recommended to be equal of CPU Cores on hardware.
There is always a master application, that will create workers. Each worker will create http + socket.io listeners which technically will be bound to master socket and routed from there.
http requests will be routed for to different workers while sockets will be routed on connection moment, but then that worker will handle this socket until it gets disconnected.
I have an nodejs chat app where multiple clients connect to a common chat room using socketio. I want to scale this to multiple node processes, possibly on different machines. However, clients that connect to the same room will not be guaranteed to hit the same node process. For example user 1 will hit node process A and user 2 will hit node process B. They are in the same room so if user 1 sends a message, user 2 should get it. What's the best way to make this happen since their connections are managed by different processes?
I thought about just having the node processes connect to redis. This at least solves the problem that process A will know there's another user, user 2, in the room but it still can't send to user 2 because process B controls that connection. Is there a way to register a "value changed" callback for redis?
I'm in a server environment where I can't control any of the routing or load balancing.
Both node.js processes can be subscribed to some channel through redis pub/sub and listen to messages which you pass to this channel. For example, when user 1 connects to process A on the first machine, you can store in redis information about this user along with the information which process on which machine manages it. Then when user 2, which is connected to process B on the second machine, sends a message to user 1, you can publish it to this channel and check which process on which machine is responsible for managing communication with user 1 and respond accordingly.
I have done(did) some research on this. Below my findings:
Like yojimbo87 said you first just use redis pub/sub(is very optimized).
http://comments.gmane.org/gmane.comp.lang.javascript.nodejs/22348
Tim Caswell wrote:
It's been my experience that the bottleneck is the serialization and
de-serialization of the data, not the actual channel. I'm pretty sure
you can use named pipes, but I'm not sure what the API is. msgpack
seems like a good format for the data interchange. There are a few
libraries out there that implement msgpack or ipc frameworks on top of
it.
But when serialization / deserialization becomes your bottle-neck I would try to use https://github.com/pgriess/node-msgpack. I would also like to test this out, because I think the sooner you have this the better?