Socket.io:如何使用Socket.io-redis适配器统计一个房间中的客户端
我开始使用带有多个节点的Socket.io构build聊天服务器。 它使用Socket.io-redis将所有服务器连接在一起,并使用空间进行消息传递。
当客户端连接到服务器时,我将客户端连接到某个房间。
io.on('connection', function(socket){ socket.join("CLIENT_1"); });
所以我想获得连接到房间"CLIENT_1"
的客户端数量,
io.sockets.adapter.rooms["CLIENT_1"];
但是我只能从当前进程获得连接。 如何从通过redis适配器连接的所有服务器进程获得连接?
我经历了这个问题:
如何检查套接字是否存活(连接)在带有多个节点和socket.io-redis的socket.io中
但它并没有帮助我。
感谢提前。
在撰写本文时:
redis适配器扩展了基本适配器 ,但它只覆盖/添加以下属性:
-
onmessage
-
broadcast
-
add
-
del
-
delAll
有了你的这个代码:
io.sockets.adapter.rooms["CLIENT_1"];
你正在查询rooms
财产 。 这不会被redis适配器覆盖,所以你实际上正在查询基本适配器,它只知道当前进程中的房间/客户端。
为什么redis适配器不覆盖rooms
属性? 因为为了匹配上面的确切呼叫签名, 每次访问属性时都必须查询redis实例来构造一个包含所有房间和连接的对象。 不好。 (这是除非你可以找出如何计算对象值的时候,他们的价值查询。)
如果要获取群集中所有进程的"CLIENT_1"
空间的连接数,则必须使用"CLIENT_1"
方法将该function添加到适配器本身 :
/** * 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,这应该是所有其他适配器实现的基础适配器接口的一部分。 这是一个常见的问题。
这个方法完美的工作:
io.sockets.adapter.clients(["room1"], function(err, clients){ console.log("total clients in room1: %d", clients.length); })
另一种方法是在socket.io-redis 3.1.0中使用customRequest / customHook方法。 我试过了,它工作。 详情在这里。 https://github.com/socketio/socket.io-redis/issues/137