【问题标题】:socket io rooms names and number of users inside specific roomsocket io 房间名称和特定房间内的用户数
【发布时间】:2018-10-22 20:09:09
【问题描述】:

我正在尝试使用 socket.io 版本构建一些基本的聊天(基于房间):

"socket.io": "^2.1.1"
"socket.io-client": "^2.1.1"

我有一些基本问题,无论我如何寻找它们,都找不到任何有效的答案。

  1. 当用户进入特定房间时,我正在这样做(在服务器中) socket.join(roomName) 所以只有当至少有一个插座连接到这个房间时,房间才“存在”?

  2. 我想创建一个包含房间名称和参与人数的屏幕 - (是否可以通过客户端 socketIO 的对象获取它?),我发现可以获取房间名称(服务器端)通过使用io.sockets.adapter.rooms,但我得到了非常奇怪的字符串,这些字符串绝对不是房间名称。

  3. 我正在尝试在每个房间内创建一个页面,显示连接到该房间的用户(使用socket.join(roomName) 进入房间的连接)

我是 socket.io 的新手,希望有人可以帮助我更好地了解如何使用它,以及我在这里缺少什么。

谢谢!

【问题讨论】:

    标签: javascript node.js socket.io


    【解决方案1】:

    确实,只要有一个客户端连接,socket.io 房间就存在。此外,一旦最后一个客户端将其作为shown here 留在套接字适配器中,它就会被销毁以释放内存:

    if (this.rooms[room].length === 0) delete this.rooms[room];
    

    要获得真实的房间名称,您必须在服务器端跟踪它们。最简单的方法是按房间名称索引的用户计数对象。

    const usersByRooms = {}
    

    当一个新的套接字连接时,你会首先发送这个完整的对象

    socket.emit('getAllRooms' usersByRoom)
    

    当你在客户端收到它时,通过它的键迭代这个对象

    socket.on('getAllRooms', (usersByRoom) => {
      Object.keys(usersByRoom).forEach(roomName =>
        console.log(roomName, usersByRoom[roomName]))
    })
    

    我假设您的页面需要实时更新连接到您房间的客户端数量。为此,您需要一种方法来广播房间的用户数量(如果房间发生变化),并相应地更新您的usersByRooms 缓存,如下所示:

    const updateCount = roomName => {
      const userCount = io.sockets.clients(roomName).length
      // we do not update if the count did not change
      if (userCount === usersByRoom[roomName]) { return }
      usersByRoom[roomName] = userCount
      io.emit('updateCount', { roomName, userCount })
    }
    

    使用这两个方法的回调,每次socket加入和离开房间成功时都需要调用这个方法:

    socket.join(roomName, () => {
      updateCount(roomName)
    })
    
    socket.leave(roomName, () => {
      updateCount(roomName)
    })
    

    您现在可以挂钩到 socket.io#2332 中添加的新 disconnecting 事件,以防您的客户端断开连接或简单地关闭您的应用程序以将新计数广播到套接字连接到的任何房间。

    socket.on('disconnecting', () => {
      const rooms = socket.rooms.slice()
      // ...
    })
    

    这种方法可能有点棘手,因为您需要跟踪正在断开连接的套接字的房间,并在套接字完成断开连接后立即更新它们。

    一个更简单的方法是在每次套接字断开连接后立即遍历所有房间并调用updateCount,因为该方法仅在房间的用户数量发生变化时广播一个事件,除非你有数以千计的房间。

    socket.on('disconnected', () => {
      Object.keys(usersByRooms).forEach(updateCount)
    })
    

    请注意,如果您使用的是套接字集群,它会有点棘手,但我假设是正常设置。

    【讨论】:

      【解决方案2】:
      1. 是的,一个房间只有在至少有一个成员时才存在,如果当前没有任何成员,调用 socket.join(roomName) 将创建一个。

      2. 好的,所以检查 io.sockets.adapter.rooms 是在内部检查的方法,只有您看到的奇怪字符串是套接字 ID,因为(来自文档):'为了您的方便,每个套接字都会自动加入一个由它的 id(参见 Socket#id)。这使得将消息广播到其他套接字的变得容易,套接字 ID 看起来类似于:'PZDoMHjiu8PYfRiKAAAF'

        如果您只需要房间列表,则需要跟踪定义的房间名称,而不是依赖于 socket.io 状态。

      3. 获取连接到房间的套接字列表如下:

        let socketsOfRoom1 = io.sockets.clients('chatroom1');
        let numberOfClientsInRoom1 = socketsOfRoom1.length;
        
        console.log(numberOfClientsInRoom1);
        socketsOfRoom1.forEach((socket) => {
            console.log(socket)
        });
        

      【讨论】:

      猜你喜欢
      • 2016-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2013-08-08
      • 1970-01-01
      • 2013-01-03
      • 2019-06-03
      相关资源
      最近更新 更多