-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Latest Socket.io and pm2 causing issues when using -i max #637
Comments
if you're using more than one cpu, users can hit different processes with their requests try to keep shared state somewhere, in redis for example |
So it WAS because of my not following of "stateless". Gotcha, gotta move that user list to redis. Silly me. Thanks. Edit: Unitech, if you can also check this out, it'd be great. Now that I re-read my own post and tested, it still doesn't make sense to me why not being stateless would cause socket.io not to be found. It would make sense for the app to crash, but not to not find socket.io. Thanks. |
Cluster module doesn't play well with Socket.io 1.x They ask to do sticky load balancing in order to redirect each user to the same process (http://socket.io/blog/introducing-socket-io-1-0/#scalability) and the Node cluster module does not permit this. The first solution I see is to fork_mode processes and attributing them different port (via JSON conf). Then with Nginx to do the sticky load balancing (http://socket.io/docs/using-multiple-nodes/#nginx-configuration) The second solution would be to use the https://github.com/indutny/sticky-session, but unfortunately I can't embed it in PM2. In conclusion I don't really like this latest socket.io version, as it break the stateless paradigm. |
sticky-session looks fishy, I mean you can't reconnect with different ip address for example. But they do recommend redis as the second option, what's wrong with that? |
If I understood well, the redis stuff is about passing events between processes (http://socket.io/docs/using-multiple-nodes/#passing-events-between-nodes) And as written on the scalability page: |
So we'll leave it at, Socket.IO is the issue, pm2 is fine and nothing we could do about it. Sticky-Session throws a random error after using it for ever so long according to some posts. This is something to be discussed with Socket.IO. Thanks guys. |
Please try to link socket.io issues to this thread so that we might follow them. Closing this as a non-pm2 issue, feel free to comment or discuss here. |
I got same issue! If I did try to run single instance it worked fine, but got a problem for multiple instances. |
set the protocol to ws from client side while connecting Client Side - somewhere in jsio.connect({transports: ['websocket']}) Server side - doing this is solving the problemio.adapter(redis({ host:SETTINGS.redis.host, port: SETTINGS.redis.port })); NoteIt will be a problem with supporting IE and other old browsers as they don't support native websockets, if the application browser compatibility is not an issue this seems a solution. |
@deathlord87 answer helped, but I still get, occasionally, "failed: Error during WebSocket handshake: Unexpected response code: 502". Anyone knows how to fix it? |
the 502 error comes when there's a requirement of the client when set to server to handle xhr-long polling or other protocols other than websockets or if the websocket protocol is not supported. |
Hi, with a cluster requests may arrive to different workers, which will break handshake protocol. Can pm2 use the same way as indutny/sticky-session to passing request to child process? |
I use a system where I store my sessions in redis, but load the sessions to the server on a connect. This way my system is "stateless" but faster than always having to talk to the redis server. What is pm2 doing in the background that makes it to where we can't create sticky sessions? |
This isn't necessarily a pm2 issue, but using pm2's command line options prevents all of the public code out there from being used (as they require you do the cluster calls yourself). What would you suggest? |
I know this one is old and closed, but I really didn't find a simple straight forward solution — or I miss it while searching around in docs anywhere (did not help that socket.io is currently down for days). FWIW I wanted to share what seems to work for me. This solution might break old browsers that does not support true websockets, but this is IE9 and below. Our application does not support those anyways, so... Swapping the So on the server (need to use redis as an adaptor to socket.io):
And on the client:
I hope it helps someone out there. Took me many hours of trial and error to figure out. |
Hi, I succeeded (it was a bit tricky... for me at least...) to implement an Apache Proxy/Balancer "load balancing" between two nodes managed with PM2. These nodes implement both an Express server and a Socket.IO server (polling or websocket - transports order has not been modified - thus fully compatible with older browsers not implementing websockets).
Client App (both HTTPs and Socket.io) ==> Apache Proxy (listening on 443 - SSL/TLS) ==> PM2/Nodes (listening on 3027 and 3028 for instance) I didn't use sticky-session module, nor REDIS. But it's "sticky" from the Apache point of view. If anyone is interested, please reply or contact me and I'll give more information. Apache configuration: <VirtualHost>
...
<Proxy balancer://socket>
BalancerMember ws://mybackend.mydomain.com:3027 route=3027 retry=1 acquire=1000
BalancerMember ws://mybackend.mydomain.com:3028 route=3028 retry=1 acquire=1000
ProxySet lbmethod=byrequests
ProxySet nofailover=on
ProxySet timeout=1000
ProxySet stickysession=ROUTEPORT
ProxySet forcerecovery=On
</Proxy>
<Proxy balancer://myapp>
BalancerMember http://mybackend.mydomain.com:3027 route=3027
BalancerMember http://mybackend.mydomain.com:3028 route=3028
ProxySet lbmethod=byrequests
ProxySet nofailover=on
ProxySet timeout=1000
ProxySet stickysession=ROUTEPORT
ProxySet forcerecovery=On
</Proxy>
RewriteEngine On
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) balancer://socket/$1 [P,L]
RewriteEngine On
RewriteCond %{QUERY_STRING} transport=polling [NC]
RewriteRule /(.*) balancer://myapp/$1 [P,L]
RewriteEngine On
RewriteCond %{REQUEST_SCHEME} ws [NC]
RewriteRule /(.*) balancer://socket/$1 [P,L]
# Proxy also serves HTTP requests for another app (node listening on 3013)
# multiple other apps could be configured the same way
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/otherapp [NC]
RewriteRule /(.*) http://mybackend.mydomain.com:3013/$1 [P,L]
RewriteEngine On
RewriteCond %{REQUEST_SCHEME} http [NC]
RewriteCond %{REQUEST_URI} !^/otherapp [NC]
RewriteRule /(.*) balancer://myapp/$1 [P,L]
</VirtualHost> Cookie management in the Node/Express server:
|
Hello @houmark and @deathlord87 , I wonder that do not I need to use I tested your way in a sample chat app. (http://socket.io/get-started/chat/) I ran the app cluster mode with 2 cores of my CPU by using PM2. So actually I ran 2 instances. When I connect to the app on 2 different browser which are present at 2 different machines and if I connected to the
If I use only one browser to connect to the app the console outputs to be as follows;
If I connected to
I think that result shows me that PM2 and Socket.IO run properly! On the other hand, although If I connect different instances with browsers (browser A on instance 1 and browser B on instance 2) and if I write In normal circumstances I need to configure pub/sub methods to share Socket messages, right? Thanks gentlemen. I never encountered with this way nowhere on the net. EditFor an app that's run on only 1 server everything is OK. However, when using an Nginx load balancer and a second App server, Redis store usage in a Socket.io app cannot save me :) And it throws the message as follows;
Actually this situation had already discussed on #1942 and its solution is over here socketio/socket.io#1942 (comment). Also I divided ports of every App instance on Nginx as directed Now, my app runs without any error. |
Socket.io websocket transport is a solution for client / server as long the "client" is a browser.. From a node.js script, this doesn't seem to work at all (which is pretty strange) |
@nimatullah thank god someone did this. Insane ❤️ |
When I launch my app.js file via pm2 start app.js -i max I get the following error on client end
" failed: Connection closed before receiving a handshake response "
when I launch the app.js via "pm2 start app.js" it works fine.
I utilize socket.io in my application on apache. The error logs are empty, but I do notice that it emits a console.log("hello world"); twice upon start from each start up on each of the cores. The websocket then keeps connecting and disconnecting.
One thing I think it could be, is that it's supposed to be "stateless", and I hold a list of online users in users = {};
But why would it work when it's only one CPU vs 4?
The text was updated successfully, but these errors were encountered: