【问题标题】:Keep track of connected sockets with socket.io使用 socket.io 跟踪连接的套接字
【发布时间】:2016-09-29 05:45:55
【问题描述】:

如何跟踪socket.io 中所有连接的客户端?

我在服务器上试过这个:

let numSockets = 0;

io.on('connection', (socket) => {
  io.sockets.emit('numSockets', ++numSockets);

  socket.on('disconnect', () => {
    io.sockets.emit('numSockets', --numSockets);
  });
});

这在客户端:

const socket = io();

socket.on('numSockets', function (numSockets) {
  console.log(numSockets);
});

它确实打印了一个数字,但是这个数字,但是,如果我打开 2 个窗口,它会显示 4 个连接的套接字。

这是正确的做法吗?

我想要实现的是在我网站的侧边栏中打印已连接套接字的 ID 列表,并让用户根据需要设置用户名(而不是自动生成的 ID)。

但在继续此之前,我会确保我能够以正确的方式跟踪套接字。

【问题讨论】:

    标签: javascript node.js sockets websocket socket.io


    【解决方案1】:

    我不认为io.sockets.emit(io.of('/').connected) 是一个好主意,因为它会发送一个包含大量数据的套接字对象散列:-)

    您可以尝试以下功能:

    function findUsersConnected(room, namespace) {
      var names = [];
      var ns = io.of(namespace || "/");    
    
      if (ns) {
        for (var id in ns.connected) {
          if(room) {
            var roomKeys = Object.keys(ns.connected[id].rooms);
            for(var i in roomKeys) {
              if(roomKeys[i] == room) {
                if (ns.connected[id].username) {
                  names.push(ns.connected[id].username);
                } else {
                  names.push(ns.connected[id].id);
                }  
              }
            }
          } else {
            if (ns.connected[id].username) {
              names.push(ns.connected[id].username);
            } else {
              names.push(ns.connected[id].id);
            }  
          }
        }
      }
      return names.sort();
    }
    

    返回连接到命名空间中房间的用户数组。如果套接字没有socket.username 属性,则使用socket.id。

    例如:

    var usersConnected = findUsersConnected();
    var usersConnected = findUsersConnected('myRoom');
    var usersConnected = findUsersConnected('myRoom', '/myNamespace');
    

    【讨论】:

      【解决方案2】:

      Namespace#connected 对象包含连接到特定命名空间的所有套接字(以它们的 id 为键)。

      要检索默认命名空间 (/) 的套接字 id:

      let clientIds = Object.keys( io.of('/').connected );
      

      (其中io 是服务器实例)

      【讨论】:

      • 所以我应该创建一个middleware 并在其中使用io.sockets.emit(io.of('/').connected) 来告诉所有客户端何时连接了新套接字?
      • @mortensen 是的,这将向所有连接的客户端发送一个套接字 ID 列表。
      【解决方案3】:

      截至今天,socket.io 在服务器端实现了一个名为 fetchSockets() 的函数来检索服务器端当前连接的所有套接字。 (来源:https://socket.io/docs/v4/server-instance/#fetchSockets)

      然后你可以像这样使用它:

      const io = require("socket.io")
      
      async function retrieveSockets() {
          const connectedSockets = await io.fetchSockets()
      }
      

      据我测试,您甚至可以在套接字上执行操作,例如发出事件、加入房间...等

      【讨论】:

        【解决方案4】:
        const count = io.engine.clientsCount;
        

        这似乎是一种更具包容性的方法,并且可能与主命名空间中的 Socket 实例数相同,如下所示。但根据命名空间和使用情况,它们可能会有所不同。

        const count2 = io.of("/").sockets.size;
        

        https://socket.io/docs/v4/server-api/#engineclientscount

        【讨论】:

          【解决方案5】:

          我相信是Object.keys(io.sockets.connected).length。检查服务器apihttp://socket.io/docs/server-api/

          【讨论】:

            猜你喜欢
            • 2012-11-08
            • 2015-11-23
            • 1970-01-01
            • 1970-01-01
            • 2018-06-03
            • 2020-11-11
            • 1970-01-01
            • 2011-10-15
            • 1970-01-01
            相关资源
            最近更新 更多