首页 > 解决方案 > socket io 房间名称和特定房间内的用户数量

问题描述

我正在尝试使用 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 的新手,我希望有人可以帮助我更好地理解如何使用它,以及我在这里缺少什么。

谢谢!

标签: javascriptnode.jssocket.io

解决方案


确实,只要有一个客户端连接到它,socket.io 房间就存在。此外,一旦最后一个客户端离开它,它就会被销毁以释放内存,如下面的套接字适配器所示:

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)
})

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


推荐阅读