我开始使用带有多个节点的Socket.io构建聊天服务器。它使用Socket.io-redis将所有服务器连接在一起,并使用rooms进行消息传递。
当客户端与服务器连接时,我将客户端加入某个房间。
io.on('connection', function(socket){
socket.join("CLIENT_1");
});
所以我想让连接到"CLIENT_1"
房间的客户数量
io.sockets.adapter.rooms["CLIENT_1"];
但我只从当前进程获得连接。如何从通过redis适配器连接的所有服务器进程获得连接?
我已经完成了这个问题:
How to check socket is alive (connected) in socket.io with multiple nodes and socket.io-redis
但它并没有帮助我。
感谢您提前。
答案 0 :(得分:7)
撰写本文时:
redis adapter extends the base adapter,但它只会覆盖/添加以下属性:
onmessage
broadcast
add
del
delAll
使用您的此代码:
io.sockets.adapter.rooms["CLIENT_1"];
您正在查询the rooms
property。 这并没有被redis适配器覆盖,因此您实际上是在查询基本适配器,它只知道当前进程中的房间/客户端。
为什么redis适配器没有覆盖rooms
属性?因为为了匹配上面的确切调用签名,它必须查询redis实例以在每次访问属性时构造包含所有房间和连接的对象。不好。 (除非你能够在查询它们的值时弄清楚如何计算对象值。)
如果您希望获得群集中所有进程的"CLIENT_1"
会议室的连接数,则必须使用以下方法将该功能添加到the adapter itself:< / p>
/**
* Count the number of connections in a room.
*
* @param {String} room id
* @param {Function} callback (optional)
* @api public
*/
Redis.prototype.numClients = function(room, fn){ ... }
其中您将查询redis数据库实例。
IMO,这应该是所有其他适配器实现的基本适配器接口的一部分。 It's a common problem.
答案 1 :(得分:4)
这种方法非常有效:
io.sockets.adapter.clients(["room1"], function(err, clients){
console.log("total clients in room1: %d", clients.length);
})
答案 2 :(得分:0)
另一种方法是在socket.io-redis 3.1.0中使用customRequest / customHook方法。我试过,它的工作原理。细节在这里。 https://github.com/socketio/socket.io-redis/issues/137