diff --git a/src/mes/indexMes/index.js b/src/mes/indexMes/index.js index f9b95b3..449e9eb 100644 --- a/src/mes/indexMes/index.js +++ b/src/mes/indexMes/index.js @@ -340,18 +340,35 @@ const useIndexMesEvent = props => { [currentContent, sModelsId, sModelType] ); + const { webSocket: ws, userinfo } = props.app; + const { url } = ws || {}; + const wsRef = useRef(ws); + useEffect(() => { + if (url) { + wsRef.current = ws; + } + }, [url]); + useEffect(() => { const connectWs = () => { - if ( - props.app.webSocket === null || - props.app.webSocket?.readyState !== WebSocket.OPEN - ) { - console.log("================webSocket连接======================"); + if (!wsRef.current || wsRef.current.readyState === WebSocket.CLOSED || wsRef.current.readyState === WebSocket.CLOSING) { + console.log("================webSocket不存在或已关闭,创建webSocket连接======================"); props.dispatch({ type: "app/createWebSocket", payload: { reStart: true, dispatch: props.dispatch } }); + return; } + if (wsRef.current.readyState !== WebSocket.OPEN) return; + const message = { flag: "connectTest", sId: "test", sendFrom: userinfo.sId }; + wsRef.current.send(JSON.stringify(message)); + window.wsTimer = setTimeout(() => { + console.log("================未收到Test返回消息,webSocket重新连接======================"); + props.dispatch({ + type: "app/createWebSocket", + payload: { reStart: true, dispatch: props.dispatch } + }); + }, 3000); }; connectWs(); @@ -359,7 +376,10 @@ const useIndexMesEvent = props => { connectWs(); }, 50000); - return () => clearInterval(timer); + return () => { + clearInterval(timer); + clearTimeout(window.wsTimer); + } }, []); useEffect(() => { diff --git a/src/models/app.js b/src/models/app.js index edea1df..46fb7a1 100644 --- a/src/models/app.js +++ b/src/models/app.js @@ -577,22 +577,102 @@ export default { if (userinfo.sUserLoginType) { url = `${config.ws_host}websocket/${userinfo.sId}?sLoginType=${userinfo.sUserLoginType}`; } - if (reStart) { + if (true) { // const webSocket = yield select(state => state.app.webSocket); // if (webSocket === null) { // return null; // } - url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true`; + url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&createTime=${new Date().getTime()}`; if (userinfo.sUserLoginType) { - url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&sLoginType=${userinfo.sUserLoginType}`; + url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&createTime=${new Date().getTime()}&sLoginType=${userinfo.sUserLoginType}`; } } + // 清理旧的WebSocket连接和定时器 + let oldWebSocket = yield select(state => state.app.webSocket); + if (oldWebSocket) { + // console.log('发现旧的WebSocket连接,准备清理:', oldWebSocket); + // console.log('旧WebSocket连接状态:', oldWebSocket.readyState); + try { + // 移除所有事件监听器 + oldWebSocket.onopen = null; + oldWebSocket.onclose = null; + oldWebSocket.onerror = null; + oldWebSocket.onmessage = null; + oldWebSocket.onmessageTmp = null; + oldWebSocket.homeAction = null; + + // 关闭连接 + if (oldWebSocket.readyState === WebSocket.OPEN || oldWebSocket.readyState === WebSocket.CONNECTING) { + oldWebSocket.close(1000, '正常关闭,准备重连'); + // console.log('已关闭旧的WebSocket连接'); + } + // 断开引用,帮助垃圾回收 + oldWebSocket = null; + console.log('旧WebSocket连接已彻底清理'); + } catch (error) { + console.log('关闭旧WebSocket连接时出错:', error); + } + } else { + console.log('没有发现旧的WebSocket连接'); + } + + // 清除所有定时器 + clearTimeout(window.wsTimer); + clearTimeout(config.timerServer); + clearTimeout(config.serverTimer); + window.wsTimer = null; + config.timerServer = null; + config.serverTimer = null; + + // 清理全局变量 + window.wsHistoryArgs = undefined; + window.onmessageTmp = undefined; const reset = (ws, config1) => { clearTimeout(config1.timerServer); clearTimeout(config1.serverTimer); start(ws, config1); }; const start = (ws, config1) => { + if (!ws.originalSend) { + ws.originalSend = ws.send.bind(ws); + } + ws.send = (...args) => { + const value = utils.convertStrToObj(args[0], {}); + const { + key, + flag, + sendFrom, + sId, + } = value; + if ((key && flag && !['release', 'noAction'].includes(flag) && sendFrom && sId) || flag === 'connectTest') { + // 3s内没返回消息,则重新创建ws,重新发送 + clearTimeout(window.wsTimer); + window.wsTimer = setTimeout(() => { + // 检查当前WebSocket连接状态 + if (ws && ws.readyState === WebSocket.OPEN) { + console.log('================WebSocket连接正常但超时未收到消息,重新发送信息======================'); + // 先尝试重新发送消息,而不是直接创建新连接 + ws.originalSend.apply(ws, args); + } else { + console.log('================超时未收到WebSocket消息,重新创建ws并发送信息======================'); + window.wsHistoryArgs = args; + ws.onmessageTmp && (window.onmessageTmp = ws.onmessageTmp); + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } }); + } + }, 3000); + } + ws.originalSend.apply(ws, args); + }; + + if (window.wsHistoryArgs) { + ws.send(...window.wsHistoryArgs); + window.wsHistoryArgs = undefined; + } + if (window.onmessageTmp) { + ws.onmessageTmp = window.onmessageTmp; + window.onmessageTmp = undefined; + } + clearTimeout(config1.timerServer); config1.timerServer = setTimeout(() => { const message = { sendFrom: userinfo.sId, connectTest: 'test' }; // param 存放其它参数 keyName 需要放入Redis的数据key,keyValue 需要放入Redis的数据key 的值 ws.send(JSON.stringify(message)); @@ -665,19 +745,54 @@ export default { const msgData = JSON.parse(msg.data); dispatch({ type: 'app/changeMachineData', payload: { ...msgData.msg || {} } }); } + } else if (window.tempWsAction) { + window.tempWsAction(msg); } }; ws.onmessage = (msg) => { + clearTimeout(window.wsTimer); + window.xlyWsTimerFun && window.xlyWsTimerFun(); reset(ws, config); + ws.onmessageTmp?.(msg); ws.homeAction(msg); }; ws.onclose = (e) => { /* 当客户端收到服务器端发送关闭请求,触发onclose事件 */ console.log('webscoket关闭!!', e); + // 清理定时器 + clearTimeout(window.wsTimer); + clearTimeout(config.timerServer); + clearTimeout(config.serverTimer); + window.wsTimer = null; + config.timerServer = null; + config.serverTimer = null; + console.log('3', e); + + // 自动重连 + if (e.code !== 1000) { // 非正常关闭 + console.log('WebSocket非正常关闭,将在5秒后尝试重连'); + setTimeout(() => { + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } }); + }, 5000); + } }; ws.onerror = (e) => { /* 如果出现连接、处理、接收、发送数据异常 触发onerror */ console.log('webscoket异常!!', e); + // 清理定时器 + clearTimeout(window.wsTimer); + clearTimeout(config.timerServer); + clearTimeout(config.serverTimer); + window.wsTimer = null; + config.timerServer = null; + config.serverTimer = null; + console.log('4', e); + + // 自动重连 + console.log('WebSocket出现异常,将在5秒后尝试重连'); + setTimeout(() => { + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } }); + }, 5000); }; yield put({ type: 'saveWebSocket', payload: { webSocket: ws } }); },