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

Socket.io事件延迟一次故障排查:服务端日志正常客户端接收滞后

Socket.io客户端事件延迟一次问题修复方案

故障根因

客户端侧

React要求状态更新必须遵循不可变原则,你直接对hook_event状态调用unshift、pop修改原数组,React无法检测到状态变更,不会触发组件重渲染。直到下一次事件触发时,上次修改的数组才会被连带渲染,因此出现总是滞后一次的现象。

服务端侧

你将bodyParser中间件注册、/api路由注册逻辑放在了io.on('connection')回调内,每有一个Socket客户端连接就会重复注册一次路由和中间件,会导致后续请求被重复处理,引发异常。另外Socket.io初始化时参数格式错误,transports配置放错了位置,也可能引发连接异常。

修复代码

客户端修复后代码

// Client
import { useEffect, useState } from 'react';
import io from 'socket.io-client';
const socket = io("http://localhost:8080", { transports: ['websocket', 'polling'] });


export default function App() {
   const [hook_event, setHook_event] = useState([
     { "date": '', "name": ''},
     { "date": '', "name": ''}
   ]);
   
  
  useEffect(() => {
    const eventHandler = (date, name) => {
      // 使用函数式更新,基于旧状态生成新数组,触发正常重渲染
      setHook_event(prevState => [
        {date, name},
        prevState[0]
      ])
    }
    socket.on('FromAPI', eventHandler);
    // 组件卸载时移除监听,避免内存泄漏
    return () => socket.off('FromAPI', eventHandler);
  }, []);

  return (
    <>      
       <p>Date : {hook_event[0].date} and {hook_event[0].name}</p>
       <p>Date : {hook_event[1].date} and {hook_event[1].name}</p>
    </> 
  );
};

注:原本冗余的date、name两个单独状态已移除,所有数据统一存在hook_event中管理即可。

服务端修复后代码

// Server
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http, {
    transports: ['websocket', 'polling'],
    cors: {
        origin:'*'
    }
});
const bodyParser = require("body-parser");

// 中间件、路由统一在全局注册
app.use(bodyParser.json());
app.post('/api', (req, res) => {
    const x = req.body[0];
    const dates = x.created_date; 
    const name = x.name; 
    // 原代码x.watchlist[Object]为错误写法,请根据实际业务调整取值逻辑,此处为示例
    const watchlist = x.watchlist;
    if (watchlist == "Matched"){
      console.log("Date :", dates)
      console.log("Name :", name)
      io.emit('FromAPI', dates, name);
    } else {
      console.log("Unmatch")
    }
    res.status(200).end("Successfully");
});

const PORT = 8080;

io.on('connection', socket => {
  console.log('Socket connected');
  socket.on('disconnect', () => { console.log('Socket disconnected')});
});

http.listen(PORT, () => {
  console.log(`Server : http://localhost:${PORT}`);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:27:01