You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js Socket.io项目:添加Socket属性后获取username返回undefined

问题解决:Socket.io中socket.data.username在leave事件中返回undefined

可能原因与对应解决方法

1. Socket.io版本兼容性问题

如果你的Socket.io版本低于3.x,socket.data这个API还不存在,直接使用会导致属性未定义。此时可以直接将用户名挂载到socket实例上替代socket.data.username:

// join game事件中
socket.username = username;

// leave game事件中
console.log(socket.username + ' left the game');
connectedUsers.delete(socket.username);

若使用4.x+版本,socket.data是官方推荐的连接数据存储方式,问题大概率出在客户端逻辑或连接生命周期上。

2. 客户端触发leave事件时连接已更换

当用户通过页面跳转(如window.location.href)进入/game页面时,浏览器会断开原WebSocket连接,新页面会建立全新的socket连接——这个新连接从未触发过join game事件,自然没有username属性。

解决办法:

  • 跳转前先触发leave game事件,确保原连接完成清理:
    // 客户端代码
    socket.emit('leave game', () => {
        window.location.href = '/game';
    });
    
  • 改用单页应用路由(如React Router、Vue Router),避免页面刷新,保持socket连接的持续性。

3. 未处理意外断开的情况

用户直接关闭页面或网络中断时,不会主动触发leave game事件,此时需要监听socket的disconnect事件来清理用户名。

修正后的完整服务端代码

io.on('connection', (socket) => {
    console.log('a user connected');
    io.emit('update users', Array.from(connectedUsers));
  
    socket.on('join game', (username) => {
        console.log(username + ' joined the game');
        // 避免重复添加同名用户
        if (!connectedUsers.has(username)) {
            connectedUsers.add(username);
            socket.data.username = username;
            io.emit('update users', Array.from(connectedUsers));
        }
        socket.emit('redirect', '/game');
    });

    socket.on('leave game', () => {
        if (socket.data.username) {
            console.log(socket.data.username + ' left the game');
            connectedUsers.delete(socket.data.username);
            io.emit('update users', Array.from(connectedUsers));
            delete socket.data.username;
        }
    });

    // 处理意外断开连接的情况
    socket.on('disconnect', () => {
        if (socket.data.username) {
            console.log(socket.data.username + ' disconnected');
            connectedUsers.delete(socket.data.username);
            io.emit('update users', Array.from(connectedUsers));
        }
    });
});

额外注意事项

  • 加入用户前检查connectedUsers中是否已存在同名用户,避免重复添加。
  • 在leave game和disconnect事件中先判断username是否存在,避免出现undefined left the game的无效日志。

内容的提问来源于stack exchange,提问作者James Kohls

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:42:58