14

我开始使用具有多个节点的Socket.io构建聊天服务器。它使用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 中检查套接字是否处于活动状态(已连接)

但这对我没有帮助。

感谢提前。

4

4 回答 4

9

在撰写本文时:

redis 适配器扩展了基本适配器,但它只覆盖/添加了以下属性:

  • onmessage
  • broadcast
  • add
  • del
  • delAll

使用您的此代码:

io.sockets.adapter.rooms["CLIENT_1"];

您正在查询rooms属性这没有被 redis 适配器覆盖,因此您实际上是在查询基本适配器,它只知道当前进程中的房间/客户端。

为什么redis适配器没有覆盖rooms属性?因为为了匹配上面的确切调用签名,每次访问该属性时,它都必须查询 redis 实例以构造一个包含所有房间和连接的对象。不好。(除非您可以在查询对象值时弄清楚如何计算对象值。)

如果您想获得"CLIENT_1"集群中所有进程与房间的连接数,您必须使用如下方法将该功能添加到适配器本身

/**
   * 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 db 实例。

IMO,这应该是所有其他适配器实现的基本适配器接口的一部分。 这是一个常见的问题。

于 2015-06-22T17:50:41.910 回答
4

这种方法非常有效:

io.sockets.adapter.clients(["room1"], function(err, clients){
  console.log("total clients in room1: %d", clients.length);
})
于 2017-02-06T04:54:35.487 回答
1

在 7.0.0 版本中,可以通过在房间上调用 allSockets 来实现。返回集的大小是集群中所有服务器上连接到您房间的套接字数。

io.in("CLIENT_1").allSockets().then(sockets => {
  console.log("Number of clients", sockets.size)
});
于 2021-09-24T14:32:23.183 回答
0

另一种方法是使用 socket.io-redis 3.1.0 中的 customRequest/customHook 方法。我试过了,它有效。详情在这里。https://github.com/socketio/socket.io-redis/issues/137

于 2017-02-05T03:46:06.807 回答