Socket.io服务端消息推送异常:客户端收不到好友请求
问题分析与修复方案
1. 事件参数不匹配(核心问题)
客户端触发sendFriendRequest事件时,仅传递了接收者邮箱一个参数,但服务端的事件监听器期望接收recipientEmail(接收者)和senderEmail(发送者)两个参数。这会导致服务端的senderEmail变量为undefined,最终发送给接收方的是无效值,同时存在参数传递逻辑的误解。
修复方式(二选一即可)
方案一:客户端补充发送者参数
修改addFriend函数,传递接收者邮箱+当前用户(发送者)的邮箱:
const addFriend = (potentialFriend) => { socket.emit("sendFriendRequest", potentialFriend, auth.email); };
方案二:服务端从握手信息取发送者(更安全)
直接从当前连接的socket握手信息中获取发送者邮箱,避免客户端传递伪造信息:
socket.on('sendFriendRequest', (recipientEmail) => { const senderEmail = socket.handshake.query.email; const recipientSocket = userSockets.get(recipientEmail); if (recipientSocket) { console.log("sending to friend req to", recipientEmail) recipientSocket.emit('receiveFriendRequest', senderEmail); } });
2. Socket实例重复创建导致监听失效
组件每次渲染都会新建socket实例,但useEffect依赖为空数组,仅在组件首次挂载时绑定旧socket的事件监听,后续新建的socket未绑定receiveFriendRequest监听器,导致无法接收事件。
修复方式:用useRef保存Socket实例
import io from 'socket.io-client'; import { useRef, useEffect, useContext } from 'react'; const FriendOpts = ({ user2Email, locationState = null, component = null }) => { const auth = useContext(AuthContext); // 用useRef持久化socket实例 const socketRef = useRef(null); useEffect(() => { socketRef.current = io("http://localhost:8000/friends", { query: { email: auth.email }, }); const socket = socketRef.current; socket.on('connect', () => { console.log(`Connected to the friends namespace`); }); socket.on('receiveFriendRequest', (senderEmail) => { console.log(senderEmail) }); // 组件卸载时断开连接 return () => { socket.disconnect(); }; }, [auth.email]); // 用户切换时重新连接 const addFriend = (potentialFriend) => { socketRef.current.emit("sendFriendRequest", potentialFriend); }; // ... 其他组件逻辑 };
3. 可选优化:处理用户断开连接
当前服务端的userSockets Map不会在用户断开时移除无效socket,可能导致后续请求使用失效连接。添加断开处理:
friendsNamespace.on('connection', (socket) => { const email = socket.handshake.query.email; console.log(email, "joined") userSockets.set(email, socket); socket.on('disconnect', () => { userSockets.delete(email); console.log(email, "disconnected"); }); // ... 其他逻辑 });
内容的提问来源于stack exchange,提问作者Isfar Oshir
相关产品推荐
相关产品推荐

