SocketIO断开连接时获取客户端信息实现聊天室用户离开通知问题求助
问题原因
- 前端
beforeunload事件触发时页面即将卸载,异步的socket.emit请求大概率还没完成就被中断,所以服务端收不到left事件 - 你没有将用户名和对应socket实例做绑定,所以系统自动触发的
disconnect事件回调里拿不到对应用户名
解决方案
1. 服务端修改(index.js)
你原本写了多个重复的io.on('connection')回调,可以全部合并为一个,同时给每个socket实例绑定对应的用户名,直接监听系统自带的disconnect事件处理离开逻辑即可:
// 把原来所有的io.on('connection')代码删掉,替换为下面这段即可 io.on('connection', (socket) => { console.log('a user connected'); // 处理用户加入 socket.on('joined', (name) => { users.push(name); // 核心:将用户名绑定到当前socket实例上 socket.username = name; io.emit('chat message', name + " joined the chat"); }); // 处理聊天消息转发 socket.on('chat message', (msg) => { console.log('message: ' + msg); io.emit('chat message', msg); }); // 系统自带的断开连接事件,无需前端主动触发 socket.on('disconnect', () => { // 直接从当前socket实例上获取对应用户名 if (socket.username) { users = removeItemOnce(users, socket.username); io.emit('chat message', socket.username + " left the chat"); } console.log('user disconnected'); }); });
2. 前端修改(index.html)
原来的beforeunload监听可以直接删除,服务端的disconnect事件会自动兜底处理所有断开场景,哪怕用户直接断网、强制关闭页面也能正常触发离开通知,可靠性远高于前端主动触发事件。
内容的提问来源于stack exchange,提问作者Shark Coding
相关产品推荐
相关产品推荐

