房间最后一位用户离开后怎么自动解散?
在做在线协作白板项目时遇到问题,当房间最后一位用户断开连接后,房间没有自动解散。试过用WebSocket的close事件监听,但发现如果用户直接关闭页面,服务端的房间成员计数器没有及时归零。
现在用的是这样的逻辑:
socket.on('disconnect', () => {
const roomId = socket.roomId;
const members = io.sockets.adapter.rooms.get(roomId)?.size;
if (members === 1) {
deleteRoom(roomId);
}
});
但测试时发现当最后两人同时离开,偶尔会出现房间残留。控制台还报过Cannot read properties of undefined (reading 'size')错误,是不是应该用更强壮的判断条件?
你原来的问题是:取
room.get(roomId)后直接访问.size,但get()返回可能是 undefined,尤其在并发断开时,两个用户同时 disconnect,第一个进来把房间清了,第二个再进来看不到房间就炸了。另外别信客户端的“最后一个”,服务端必须以实际 adapter 的房间状态为准。加个 !room 判断兜底,再根据减一后的数量决定是否删房间,这样哪怕多个 disconnect 并发进来也安全。
顺便提醒,socket.roomId 记得在 join 时赋值,disconnect 后最好手动删掉 socket.roomId = null,避免重复触发逻辑。
io.sockets.adapter.rooms.get(roomId)会返回 undefined,这时候访问.size就会报错。你确实需要更健壮的判断逻辑。直接用下面这段代码替换你的监听逻辑就行:
另外确保
socket.roomId在用户加入房间时正确赋值,并且在用户断开连接前没有被提前清除。如果你用的是 socket.io 的默认房间机制,用户离开时默认不会自动清除房间,这点不用动。如果还想更彻底一点,可以在用户加入和离开房间时打印日志验证房间状态:
这样调试起来会更直观。