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