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
相关产品推荐
相关产品推荐

