Socket.io仅在两端重启后发消息,切换聊天室无实时消息求助
解决Socket.io实时消息异常问题
问题现象
- 仅服务端和客户端都重启后,Socket.io才能正常即时发送消息
- 用户切换聊天室后无法接收实时消息,需重启两端恢复
- 能通过
console.log看到Socket.io传来的数据,但消息无法更新到界面
服务端代码修正
1. 修复用户SocketID更新逻辑
当前addUser未处理同一用户重复添加的情况,导致切换聊天室后用户的SocketID未更新,消息仍发往旧连接。修改addUser函数:
function addUser(user: userSocketAttributes) { // 先移除该用户的旧记录,再添加新的SocketID users = users.filter(u => u.userId !== user.userId); users.push(user); }
2. 增加用户在线状态判断
发送消息前需确认接收用户是否在线,避免向无效SocketID发送消息:
socket.on("sendMessage", async (messageAttributes: socketMessageAttributes)=>{ const user = findUser(messageAttributes.recieverId); if (!user) { console.log(`用户${messageAttributes.recieverId}未在线,消息无法实时推送`); return; } const authToken = JWT_Helper_verify(messageAttributes.auth) as JwtPayload; try { const userid = await CreateCustomer.findOne({where:{id: authToken?.id}}); const support = await CreateCustomer.findOne({where: {user_username: 'support'}}); io.to(user.socketId).emit("getMessage", messageAttributes); } catch (error) { console.log(error); } })
客户端代码修正
1. 清理旧Socket连接
切换聊天室时未断开旧连接,导致多连接冲突,需在组件卸载或聊天室切换时断开旧连接:
useEffect(()=>{ // 断开之前的Socket连接 if (socket.current) { socket.current.disconnect(); } socket.current = io(socket_URL); socket.current.emit('addUser', userDetails?.role === 'support' ? data?.conversation?.recieverId : userDetails?.id); // 组件卸载时清理连接 return () => { if (socket.current) { socket.current.disconnect(); } }; }, [data?.conversation?.id])
2. 修复消息监听的闭包问题
原监听逻辑未使用函数式更新,导致无法获取最新的chatMessages状态,且未清理旧监听导致重复绑定:
useEffect(()=>{ if (!socket.current) return; const handleNewMessage = (item: any) => { if(data?.conversation?.id === item?.conversationId){ // 使用函数式更新获取最新的消息数组 setChatMessages(prevMessages => [...prevMessages, item]); } }; socket.current.on("getMessage", handleNewMessage); // 清理函数移除监听,避免内存泄漏 return () => { socket.current?.off("getMessage", handleNewMessage); }; }, [data?.conversation?.id, socket.current])
3. 切换聊天室时重新拉取消息
确保切换聊天室后能获取最新的历史消息:
useEffect(()=>{ fetchMessages(); }, [data?.conversation?.id]) // 添加聊天室ID作为依赖,切换时触发
内容的提问来源于stack exchange,提问作者kingsJayson
相关产品推荐
相关产品推荐

