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

Socket.io服务端仅接收客户端首个事件问题排查求助

问题:Socket.io客户端连续emit多个事件,服务端仅接收首个事件

我正在开发一款具备实时数据共享功能的React应用,后端采用socket.io与express,前端通过socket.io-client向服务端发送事件。页面加载时我需要发送部分数据至服务端,但当客户端emit多个事件后,服务端控制台仅能接收到首个事件的数据。

前端emit事件代码

import { useEffect, useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
import io from "socket.io-client";

const PORT = "http://localhost:3000";
const connectionOptions = {
  "force new connection": true,
  reconnectionAttempts: "Infinity",
  timeout: 10000,
  retries: 3,
  transport: ["websocket"],
};

const server = io(PORT, connectionOptions);

function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    server.emit("start");
    server.emit("end");
  }, []);

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  );
}

export default App;

服务端监听事件代码

import express from "express";
import http from "http";
import { Server } from "socket.io";
import cors from "cors";

const port = process.env.PORT || 3000;
const app = express();
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"],
  },
});

io.on("connection", (socket) => {
  console.log("Connected");

  socket.on("start", () => {
    console.log("start");
  });

  socket.on("end", () => {
    console.log("end");
  });

  socket.on("disconnect", () => {
    console.log("Disconnected");
  });
});

server.listen(port, () =>
  console.log(`server is running on http://localhost:${port}`)
);

app.get("/", (req, res) => {
  res.send("MathCollab server");
});

预期与实际输出

预期服务端控制台输出

Connected
start
end

实际服务端控制台输出

Connected
start

问题原因与解决方法

问题根源

  1. 连接时机不匹配:组件挂载时直接连续emit事件,但此时socket可能还未完成连接建立,第二个事件发送时连接未就绪,导致事件丢失。
  2. 废弃配置干扰:connectionOptions中的"force new connection": true是Socket.io旧版本配置,v4+已废弃,可能引发连接异常。

解决步骤

  1. 将socket实例初始化移至组件内部,监听connect事件,确保连接成功后再发送事件。
  2. 移除废弃的"force new connection": true配置。

修改后的前端代码

import { useEffect, useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
import io from "socket.io-client";

const PORT = "http://localhost:3000";
const connectionOptions = {
  reconnectionAttempts: "Infinity",
  timeout: 10000,
  retries: 3,
  transport: ["websocket"],
};

function App() {
  const [count, setCount] = useState(0);
  const [socket, setSocket] = useState(null);

  useEffect(() => {
    const newSocket = io(PORT, connectionOptions);
    
    // 连接成功后再发送事件
    newSocket.on("connect", () => {
      newSocket.emit("start");
      newSocket.emit("end");
    });

    setSocket(newSocket);

    // 组件卸载时断开连接
    return () => {
      newSocket.disconnect();
    };
  }, []);

  return (
    <>
      <div>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <div className="card">
        <button onClick={() => setCount((count) => count + 1)}>
          count is {count}
        </button>
        <p>
          Edit <code>src/App.jsx</code> and save to test HMR
        </p>
      </div>
      <p className="read-the-docs">
        Click on the Vite and React logos to learn more
      </p>
    </>
  );
}

export default App;

修改后服务端即可正常接收所有emit的事件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 03:52:49