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

Socket后端运行正常但React前端接收消息异常求助

Socket.IO 前端消息接收异常解决方案

问题概述

后端Socket.IO服务运行正常(sendingMessage事件中console.log(data)可正常输出),但React前端在useEffect钩子中监听receiveMessage事件时,无法触发console.log(message),偶尔能工作但刷新页面后失效,消息发送功能正常。

后端代码

const userSocketMap = {};
io.on("connection", (socket) => {
  socket.on("register-id", (username) => {
    userSocketMap[username] = socket.id;
    console.log(socket.id);
  });

  socket.on("sendingMessage", (data) => {
    const { sender, receiver, message } = data;
    const receiverId = userSocketMap[receiver];
    if (receiverId) {
      console.log(data);
      console.log("当前接收方SocketID:", receiverId); // 新增调试日志
      io.to(receiverId).emit("receiveMessage", data);
    } else {
      console.log("未找到接收方对应的Socket连接"); // 新增调试日志
    }
  });

  // 新增:清理断开连接的用户
  socket.on("disconnect", () => {
    Object.keys(userSocketMap).forEach(username => {
      if (userSocketMap[username] === socket.id) {
        delete userSocketMap[username];
      }
    });
  });
});
server.listen(3000, () => {
  console.log(`Server running on http://localhost:3000`);
});

前端相关代码

消息接收逻辑(组件内)

useEffect(() => {
  const handleMessageReceive = (data) => {
    const message = {
      sender: data.sender,
      receiver: data.receiver,
      message: data.message,
      timestamp: new Date(data.timestamp).toISOString().slice(11, 16),
    };
    console.log(message);
  };

  socket.on("receiveMessage", handleMessageReceive);

  return () => {
    socket.off("receiveMessage", handleMessageReceive);
  };
}, []);

Socket实例配置(socket.js)

import { io } from "socket.io-client";
const socket = io("http://localhost:3000");

// 新增:连接成功后自动注册用户
socket.on('connect', () => {
  console.log("当前前端SocketID:", socket.id); // 新增调试日志
  const username = localStorage.getItem('username');
  if (username) {
    socket.emit('register-id', username);
  }
});

export { socket };

核心解决方案

  • 刷新后强制重新注册用户:页面刷新会导致Socket连接重建,旧的socket.id完全失效。必须在Socket触发connect事件后,重新发送register-id给后端,更新userSocketMap中的对应关系,确保后端拿到当前有效的socket.id。
  • 清理无效Socket连接:后端新增disconnect事件监听,当用户断开连接时从userSocketMap中删除对应条目,避免残留无效的socket.id导致消息发送到已断开的连接。
  • 比对前后端SocketID:通过新增的调试日志,确认后端sendingMessage事件中输出的receiverId与前端connect事件中输出的socket.id一致。如果不一致,说明用户未完成重新注册流程。
  • 确保Socket实例全局唯一:当前配置已通过单例导出实现,无需修改,避免多实例导致事件监听分散失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:22:03