Distributed websocket, how to make people who hit different servers communicate with each other?

recently exposed to websocket, the demand is very simple, using websocket to let users participate in a 1v1 Mini Game. The
environment is distributed, and each server is multi-process, and the web server uses the nodejs,websocket framework with socket.io.

problems encountered:
first of all, in a single server survey, when using nodejs multi-process (cluster), 400 errors occurred when establishing websocket, and then it was found that it was a multi-process problem, and users could not guarantee that they would visit the same process every time when they visited the server, so the background would report an error "Session ID unknown". It may be that in order to ensure that socket.io may occasionally become long polling, it is necessary to ensure that the foreground and backend must pass a session id. But every time the page is refreshed, the re-launch of websocket should have nothing to do with the websocket before the last refresh, or it is possible that socket.io introduced session id to ensure reconnection with the server to save resources. I don"t know if my understanding is correct.
has found a lot of information on the Internet, and has also seen the recommendation scheme (http://socket.io/docs/using-multiple-nodes/) on the official website of socket.io. There are two kinds:

nginx
configure ip_hash to enable users to connect to fixed processes every time. They don"t know much about nginx before.

redis
read the most established recommended solution on the Internet is also redis. I haven"t contacted redis before, and I don"t know how it works. After roughly understanding it, I found that it is a persistent storage of key-value, similar to MemCache and mongoDB. The code example given on the official website:

var io = require("socket.io")(3000);
var redis = require("socket.io-redis");
io.adapter(redis({ host: "localhost", port: 6379 }));
The

example is very simple. It redirects the request to an adapter to connect to the redis service, but what is the principle? the solution of shared memory? I don"t understand it, so I don"t do it.

finally, I chose a silly scheme. When starting the websocket service in different sub-processes, I chose different ports. For example, a server with 8 cores will have 8 ports 3001-3008, so that when users connect to a fixed port, there will be no more 400error, but after users hit different ports, how to communicate with each other is still a problem. This is only a single server experiment, if it is a cluster. Communicating with each other is also a problem, and is it critical that users connect to the same port and the same server every time? In the final analysis, I still know too little about websocket. I hope to get some guidance and help here.


if you use Redis, I guess it is implemented using the subscription / publish function of Redis, which can well solve the problem of users communicating with each other on different servers.


Hello, I have been doing websocket distributed recently, but what I am doing is the web site, using the framework of workerman and multiple server clusters.
the following is my understanding:
if I understand correctly, your question should be how different servers communicate with each other
I think to solve the communication between different servers is to share data, so that each websocket receives the same data, and redis is memory sharing.
from an abstract point of view, if each process needs to communicate, it means that the data they accept is exactly the same, that is, the data is shared and the websocket is only responsible for transferring data.

I also recommend redis for the specific implementation.

how is the problem solved? Let's share the plan.


I took a general look at the problem of the landlord. My understanding is that the landlord has encountered a distributed problem and wants users to refresh even WEBSocket. I only have a preliminary understanding of socket.io, I am using a solution of PHP (swoole).

I'll outline my solution. Because the distributed architecture is only reserved at present, and the distributed architecture is not really deployed, the scheme may not be perfect and is for reference only.

I deal with distribution with the help of ordinary HTTP session.

first of all, I will let the user log in in a normal HTTP request, and then store the login session in redis, so that the login information is naturally distributed. Because every time you connect to WEBSocket, you will first send a normal http request, and then upgrade to websocket. At this time, there is a login key in the login cookie, because the cookie information can be read in the open phase of websocket. Compare the redis of this area, and you will know whether you are logged in or not.


the problem is that websocket session cannot serialize and save to redis, and recently encountered the same problem


  1. give up the long-rotation handshake and use the websocket handshake so that only one request is made to a specific server, and some incompatible browsers cannot use it.
  2. use nginx as the front-end distribution router ip_hash, and requests from a certain ip are sent to a port for processing
< H1 > all of the above should be adapted with socket.io-adapter, so that the socket.io of different ports (processes) can communicate with each other < / H1 >

finally, how do you make a project run on multiple ports? Is there a more elegant way to drive one by one?

Menu