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áč
相关产品推荐
相关产品推荐

