diff --git a/src/mes/indexMes/index.js b/src/mes/indexMes/index.js index 599e01f..5078552 100644 --- a/src/mes/indexMes/index.js +++ b/src/mes/indexMes/index.js @@ -332,7 +332,7 @@ const useIndexMesEvent = props => { [currentContent, sModelsId, sModelType] ); - const { webSocket: ws } = props.app; + const { webSocket: ws, userinfo } = props.app; const { url } = ws || {}; const wsRef = useRef(ws); useEffect(() => { @@ -343,8 +343,8 @@ const useIndexMesEvent = props => { useEffect(() => { const connectWs = () => { - if (!wsRef.current) { - console.log("================webSocket不存在,创建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 } @@ -352,15 +352,7 @@ const useIndexMesEvent = props => { return; } if (wsRef.current.readyState !== WebSocket.OPEN) return; - const message = { - connectTest: 'test', - key: 'test', - flag: 'test', - msg: 'test', - sId: 'test', - showType: 'test', - sendFrom: props.app.userinfo.sId, - }; + const message = { flag: "connectTest", sId: "test", sendFrom: userinfo.sId }; wsRef.current.send(JSON.stringify(message)); window.wsTimer = setTimeout(() => { console.log("================未收到Test返回消息,webSocket重新连接======================"); diff --git a/src/models/app.js b/src/models/app.js index fabd7f5..f096120 100644 --- a/src/models/app.js +++ b/src/models/app.js @@ -577,44 +577,114 @@ 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&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)); }, config1.timeoutServer); }; - const oldWebSocket = yield select(state => state.app.webSocket); const ws = new WebSocket(url); ws.onopen = function (e) { console.log('连接上 webscoket 服务端了', e); start(ws, config); - if (oldWebSocket && oldWebSocket !== ws) { - try { - oldWebSocket.close(); - console.log('================已关闭旧的WebSocket连接======================'); - } catch (error) { - console.log('================关闭旧WebSocket连接时出错======================', error); - } - } }; // 全局通用的自定义onmessage的方法 - ws.homeAction = (msg) => { - clearTimeout(window.wsTimer); + ws.homeAction = msg => { const rtmsg = JSON.parse(msg.data); if (false && rtmsg.action === 'showImg' && location.pathname.indexOf('/indexOee') < 0) { const msgData = JSON.parse(msg.data); @@ -678,16 +748,49 @@ export default { } }; 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; + + + // 自动重连 + 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('WebSocket出现异常,将在5秒后尝试重连'); + setTimeout(() => { + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } }); + }, 5000); }; yield put({ type: 'saveWebSocket', payload: { webSocket: ws } }); },