Socket.io 4.x 如何获取房间内用户的用户名列表?
Socket.IO 房间用户列表实现方案
核心思路
你需要在服务端维护socket连接与用户名的关联关系,再通过房间广播机制同步用户列表即可解决两个疑问,具体实现如下:
修改后服务端代码
// 全局存储:key为房间ID,value为该房间的用户数组(包含socketId和用户名) const roomUserMap = {} io.on('connection', socket => { socket.broadcast.emit('a user connected') // 处理用户加入房间事件 socket.on('join', (room) => { console.log(room); const { roomID, name } = room; // 1. 关联用户名与当前socket连接,解决第一个疑问 socket.username = name; socket.currentRoom = roomID; // 2. 执行加入房间操作 socket.join(roomID); // 3. 更新对应房间的用户列表 if (!roomUserMap[roomID]) { roomUserMap[roomID] = [] } roomUserMap[roomID].push({ socketId: socket.id, name: name }) // 4. 组装用户列表并广播到当前房间,解决第二个疑问 const currentUserList = roomUserMap[roomID] io.to(roomID).emit('userListUpdate', currentUserList) }); // 处理用户断开连接,清理用户列表避免脏数据 socket.on('disconnect', () => { const roomID = socket.currentRoom; if (roomID && roomUserMap[roomID]) { // 移除离开的用户 roomUserMap[roomID] = roomUserMap[roomID].filter(user => user.socketId !== socket.id) // 广播更新后的用户列表 io.to(roomID).emit('userListUpdate', roomUserMap[roomID]) } }) })
客户端新增接收代码
// 监听房间用户列表更新事件 socket.on('userListUpdate', (userList) => { console.log('当前房间用户列表:', userList) // 此处可自行编写渲染用户列表的业务逻辑 })
疑问对应解答
- 关联用户名的逻辑:Socket连接实例本身支持挂载自定义属性,你可以在用户加入房间时直接把用户名、所属房间号挂载到当前socket对象上,也可以通过全局Map结构存储
socket.id与对应用户信息的映射关系,两种方式都可以实现稳定关联。 - 发送用户列表的逻辑:每次用户加入/离开房间时更新全局存储的房间用户列表,再调用
io.to(房间ID).emit()方法向该房间内的所有客户端广播最新的用户列表,客户端监听对应事件即可拿到包含完整用户名的列表数据。
内容的提问来源于stack exchange,提问作者Ferhat Suat Erdoğan
相关产品推荐
相关产品推荐

