Socket.io:如何使用Socket.io-redis适配器计算房间中的客户端

时间:2015-06-03 16:19:26

标签: node.js socket.io socket.io-redis

我开始使用带有多个节点的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

但它并没有帮助我。

感谢您提前。

3 个答案:

答案 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