I have a server working with cluster and to make that work with socke.IO I am using sticky-session, but I have a problem with my rooms (I don't know if the way I did is the best option): The cluster is instantiating processes and each process has a specific number of rooms.
我有一个服务器和集群一起工作,让它和socke一起工作。IO我正在使用sticky会话,但是我的房间有一个问题(我不知道我这样做是不是最好的选择):集群正在实例化进程,每个进程都有特定数量的房间。
- Server
- Process 1
- Room1
- Room1
- Room2
- Room2
- Room N
- 房间N
- 1房2房N
- Process 2
- Room1
- Room1
- Room2
- Room2
- Room N
- 房间N
- 过程2房间1房间2房间N
- Process 1
- 服务器进程1房2房N进程2房2房N
The way I did to connect some user to the rooms (with only one process) is using the route, where the user access a page and when he tries to make a connection with Socket.io I check the URL and with that information I insert him in a room.
我将一些用户连接到房间(只有一个进程)的方法是使用路由,用户访问一个页面并尝试与Socket建立连接。我检查一下网址,然后把他放在房间里。
My problem is implementing this server with cluster I can not insert the user in specific rooms because there is some rooms that only exist in specific processes and sticky session put him in another process. How can I put an user in a room that is in another process ? Also The use can only to see the routes of the process he is in the server and I would like to show every rooms in the page.
我的问题是用集群实现这个服务器,我不能将用户插入到特定的房间中,因为有些房间只存在于特定的进程中,而粘性会话将用户放置在另一个进程中。如何将用户放在另一个进程中的房间?另外,只能查看服务器中进程的路由,我想显示页面中的每个房间。
I already has read about Redis-Adapter but I didn't find solutions on github using Socket.io + Cluster(Sticky-session + redis-adapter) + rooms.
我已经读过关于Redis-Adapter的文章,但是我没有找到使用Socket在github上的解决方案。io +集群(Sticky-session + redis-adapter) +房间。
Follow my code to share what I have done:
按照我的代码分享我所做的:
//Cluster.Master with simplified Code
if (cluster.isMaster) {
var workers = [];
// Spawn workers.
for (var i = 0; i < num_processes; i++) {
spawn(i);
}
// Create the outside facing server listening on our port.
var server = net.createServer({
pauseOnConnect: true
}, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var worker = workers[worker_index(connection.remoteAddress, num_processes)];
worker.send('sticky-session:connection', connection);
}).listen(process.env.PORT);
} else {
console.log('I am worker #' + cluster.worker.id);
var app = new express();
//view engine
app.set('views', './views');
app.set('view engine', 'pug');
//statics
app.use(express.static(path.join(__dirname, 'public')));
//rooms
app.use('/', rooms);
var server = app.listen(0, 'localhost'),
io = sio(server);
io.adapter(sio_redis({ host: 'localhost', port: 6379 }));
//This File has the socket events (socket.on('messageX', function(){}))
// And there I am
var realtime = require('./realtime/socketIOEvents.js')(io);
// Listen to messages sent from the master. Ignore everything else.
process.on('message', function(message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
}
3 个解决方案
#1
2
socketio-redis is a right thing to do. Every sserver/process listens to a topic in redis queue. To understand in short socketio-redis just publishes the event to every other server/process in cluster. So as far as the Rooms are concern they are just an abstraction to a group of sockets interested in listening to messages in the room.
索科蒂奥-雷迪斯是正确的选择。每个sserver/进程在redis队列中侦听一个主题。要理解的是,socketio-redis只是将事件发布到集群中的其他所有服务器/进程中。就房间而言,它们只是一组对在房间里听消息感兴趣的套接字的抽象。
Even if sockets are distributed to different servers/processes they can be a part of same room. As every message comes in, every server knows about it and passes on the to required sockets.
即使套接字分布到不同的服务器/进程,它们也可以是同一个房间的一部分。当每个消息传入时,每个服务器都知道它并传递到所需的套接字。
As far as correctness is concern, Your architecture is right also correct as your proxy decides also selectively forwards the message but it is increasing hops in a lifecycle of a message. You really do not need this proxy to handle socket routing.
就正确性而言,您的体系结构也是正确的,因为您的代理决定也有选择地转发消息,但这增加了消息生命周期中的跳数。您确实不需要这个代理来处理套接字路由。
#2
1
Here is the example code which will worked based on the room joining with.
下面是基于房间连接的示例代码。
http://www.html5gamedevs.com/topic/12321-create-a-cluster-server-with-nodejs-and-socketio/
http://www.html5gamedevs.com/topic/12321-create-a-cluster-server-with-nodejs-and-socketio/
Let me know if you have question in this post.
如果你在这篇文章中有问题,请告诉我。
#3
1
After a lot of tries I did this with a Proxy server in the top of the workers and every workers registering rooms in another server (Redis). When I connect to the server with the URL of a room, my proxy server detects which worker I am trying to connect and route my web socket connection to the right worker.
在多次尝试之后,我在工作人员的顶部使用了一个代理服务器,并且每个工作人员都在另一个服务器(Redis)中注册了房间。当我用一个房间的URL连接到服务器时,我的代理服务器检测我正在连接哪个worker,并将我的web套接字连接路由到正确的worker。
Proxy
/ | \
worker(5rooms) worker(5rooms) worker(5rooms)
\ | /
Redis
That solves my problem but it is not using socket.io-redis. How can we solve that problem with socket.io-redis? Add every users, sockets and variables in redis to make just the processing in the workers is a valid approach ?
这解决了我的问题,但它不是使用socketl .io-redis。我们如何用足球来解决这个问题?在redis中添加每个用户、套接字和变量,以使处理工作成为有效的方法?
#1
2
socketio-redis is a right thing to do. Every sserver/process listens to a topic in redis queue. To understand in short socketio-redis just publishes the event to every other server/process in cluster. So as far as the Rooms are concern they are just an abstraction to a group of sockets interested in listening to messages in the room.
索科蒂奥-雷迪斯是正确的选择。每个sserver/进程在redis队列中侦听一个主题。要理解的是,socketio-redis只是将事件发布到集群中的其他所有服务器/进程中。就房间而言,它们只是一组对在房间里听消息感兴趣的套接字的抽象。
Even if sockets are distributed to different servers/processes they can be a part of same room. As every message comes in, every server knows about it and passes on the to required sockets.
即使套接字分布到不同的服务器/进程,它们也可以是同一个房间的一部分。当每个消息传入时,每个服务器都知道它并传递到所需的套接字。
As far as correctness is concern, Your architecture is right also correct as your proxy decides also selectively forwards the message but it is increasing hops in a lifecycle of a message. You really do not need this proxy to handle socket routing.
就正确性而言,您的体系结构也是正确的,因为您的代理决定也有选择地转发消息,但这增加了消息生命周期中的跳数。您确实不需要这个代理来处理套接字路由。
#2
1
Here is the example code which will worked based on the room joining with.
下面是基于房间连接的示例代码。
http://www.html5gamedevs.com/topic/12321-create-a-cluster-server-with-nodejs-and-socketio/
http://www.html5gamedevs.com/topic/12321-create-a-cluster-server-with-nodejs-and-socketio/
Let me know if you have question in this post.
如果你在这篇文章中有问题,请告诉我。
#3
1
After a lot of tries I did this with a Proxy server in the top of the workers and every workers registering rooms in another server (Redis). When I connect to the server with the URL of a room, my proxy server detects which worker I am trying to connect and route my web socket connection to the right worker.
在多次尝试之后,我在工作人员的顶部使用了一个代理服务器,并且每个工作人员都在另一个服务器(Redis)中注册了房间。当我用一个房间的URL连接到服务器时,我的代理服务器检测我正在连接哪个worker,并将我的web套接字连接路由到正确的worker。
Proxy
/ | \
worker(5rooms) worker(5rooms) worker(5rooms)
\ | /
Redis
That solves my problem but it is not using socket.io-redis. How can we solve that problem with socket.io-redis? Add every users, sockets and variables in redis to make just the processing in the workers is a valid approach ?
这解决了我的问题,但它不是使用socketl .io-redis。我们如何用足球来解决这个问题?在redis中添加每个用户、套接字和变量,以使处理工作成为有效的方法?