WebSocket连接存储替代方案及页面刷新保连方法咨询
WebSocket 页面刷新后连接恢复方案
WebSocket 对象无法被序列化存储(sessionStorage/localStorage 仅支持原始类型),页面刷新后原有连接会被销毁,没法直接“保留”连接。但可以通过自动重连+状态恢复的方式,实现刷新后无缝恢复连接,避免调用ws.send()时出现undefined的问题。
核心解决方案
- 持久化连接状态与配置:将是否处于流数据状态(
streaming)、连接所需的configuration存储到sessionStorage,页面刷新后读取这些值自动恢复。 - 页面加载自动重连:组件初始化时检查
sessionStorage中的状态,若之前处于连接状态,则自动调用连接方法。 - 安全发送数据校验:发送数据前不仅检查
socket是否存在,还要校验连接是否处于OPEN状态。
修改后的代码实现
import { useEffect, useState } from 'react'; const YourComponent = () => { const [socket, setSocket] = useState(null); const [streaming, setStreaming] = useState(false); const [configuration, setConfiguration] = useState({ /* 你的配置默认值 */ }); const [plotData, setPlotData] = useState([]); const startConn = () => { // 从sessionStorage读取之前的配置(如果有) const savedConfig = sessionStorage.getItem('wsConfiguration'); const configToUse = savedConfig ? JSON.parse(savedConfig) : configuration; const ws = new WebSocket('wss://4z2ysa3nod.execute-api.ap-southeast-2.amazonaws.com/Test/'); setSocket(ws); ws.onopen = () => { console.log('[onopen] WebSocket connected'); setStreaming(true); // 保存连接状态和配置到sessionStorage sessionStorage.setItem('wsStreaming', 'true'); sessionStorage.setItem('wsConfiguration', JSON.stringify(configToUse)); ws.send(JSON.stringify({ action: 'start-streaming-data', data: configToUse })); }; ws.onmessage = (event) => { const data = JSON.parse(event.data); setPlotData(prevData => { const dataArray = Array.isArray(prevData) ? prevData : []; const newData = [ ...dataArray, { time: new Date().toLocaleTimeString(), data: data.graph } ]; if (newData.length > 10) { newData.shift(); } sessionStorage.setItem('plotData', JSON.stringify(newData)); return newData; }); }; ws.onclose = () => { setStreaming(false); sessionStorage.removeItem('wsStreaming'); console.log('[onclose] WebSocket disconnected'); }; ws.onerror = (error) => { console.error('[onerror] WebSocket error:', error); setStreaming(false); sessionStorage.removeItem('wsStreaming'); }; return () => { ws.close(); }; }; // 页面加载时自动恢复连接 useEffect(() => { const savedStreaming = sessionStorage.getItem('wsStreaming') === 'true'; if (savedStreaming) { startConn(); } // 读取之前保存的plotData const savedPlotData = sessionStorage.getItem('plotData'); if (savedPlotData) { setPlotData(JSON.parse(savedPlotData)); } }, []); // 流数据定时发送逻辑 useEffect(() => { let intervalId; if (streaming && socket) { intervalId = setInterval(() => { // 确保连接处于OPEN状态再发送 if (socket.readyState === WebSocket.OPEN) { const savedConfig = sessionStorage.getItem('wsConfiguration'); const configToUse = savedConfig ? JSON.parse(savedConfig) : configuration; socket.send(JSON.stringify({ action: 'start-streaming-data', data: configToUse })); } else { console.log("[wsSend] socket not in OPEN state"); } }, 1000); } else { clearInterval(intervalId); } return () => clearInterval(intervalId); }, [streaming, socket, configuration]); // 其他组件逻辑... return ( // 组件JSX... ); }; export default YourComponent;
关键改动说明
- 状态持久化:连接成功后将
streaming状态和configuration存入sessionStorage,页面刷新后自动读取并触发重连。 - 自动重连触发:新增初始化
useEffect,页面加载时检查wsStreaming标记,自动调用startConn恢复连接。 - 发送安全校验:在定时发送逻辑中,增加
socket.readyState === WebSocket.OPEN的判断,避免连接未就绪时发送数据。 - 错误处理补充:添加
onerror事件监听,处理连接异常情况并清理状态标记。
内容的提问来源于stack exchange,提问作者Flavio Andrade
相关产品推荐
相关产品推荐

