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

FE无法接收Socket.io的get-users事件(仅自身连接时例外)

问题分析与解决方案

核心问题

你遇到的问题根源在于后端发送get-users事件的方式错误:

  • 后端使用socket.emit()时,只会向触发当前事件的单个客户端发送消息,而非广播给所有在线客户端。所以只有新连接的用户自己能收到在线列表更新,其他用户完全收不到;
  • 用户断开时,触发disconnect事件的socket已经处于断开状态,此时用socket.emit()根本发不出消息,自然没人能收到列表更新。

修复方案

后端代码修改

把两处socket.emit()替换为io.emit(),这个方法会广播消息给所有在线客户端:

socket.on("new-user-add", (newUserId: String) => {
  if (!activeUsers.some((user) => user.userId === newUserId)) {
    activeUsers.push({ userId: newUserId, socketId: socket.id });
  }
  // 广播给所有在线客户端
  io.emit("get-users", activeUsers);
});

socket.on("disconnect", () => {
  activeUsers = activeUsers.filter(user => user.socketId !== socket.id);
  // 广播给所有在线客户端
  io.emit("get-users", activeUsers);
});

额外优化建议

  • 前端useEffect的清理函数可以简化,socket.disconnect()会自动移除所有事件监听,不需要手动调用off:
useEffect(() => {
  socket.current = io(process.env.REACT_APP_BE_URL);
  socket.current.emit('new-user-add', user._id);
  socket.current.on('get-users', (users) => {
    console.log('GET USERS');
    dispatch(setOnlineUsers(users));
  });
  return () => {
    socket.current.disconnect();
  };
}, [user._id]);
  • 如果新用户加入时,不需要给当前用户重复发送列表(因为刚连接时已经拿到),可以用socket.broadcast.emit()替代io.emit(),仅广播给除当前用户外的其他客户端。

内容的提问来源于stack exchange,提问作者Šimon Kováč

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:51:41