Commit a13a0b0e613c4c1db199cb0613b9334c55a92648

Authored by Min
1 parent f7ff6604

1.修改ws重连逻辑

src/mes/indexMes/index.js
@@ -332,7 +332,7 @@ const useIndexMesEvent = props => { @@ -332,7 +332,7 @@ const useIndexMesEvent = props => {
332 [currentContent, sModelsId, sModelType] 332 [currentContent, sModelsId, sModelType]
333 ); 333 );
334 334
335 - const { webSocket: ws } = props.app; 335 + const { webSocket: ws, userinfo } = props.app;
336 const { url } = ws || {}; 336 const { url } = ws || {};
337 const wsRef = useRef(ws); 337 const wsRef = useRef(ws);
338 useEffect(() => { 338 useEffect(() => {
@@ -343,8 +343,8 @@ const useIndexMesEvent = props => { @@ -343,8 +343,8 @@ const useIndexMesEvent = props => {
343 343
344 useEffect(() => { 344 useEffect(() => {
345 const connectWs = () => { 345 const connectWs = () => {
346 - if (!wsRef.current) {  
347 - console.log("================webSocket不存在,创建webSocket连接======================"); 346 + if (!wsRef.current || wsRef.current.readyState === WebSocket.CLOSED || wsRef.current.readyState === WebSocket.CLOSING) {
  347 + console.log("================webSocket不存在或已关闭,创建webSocket连接======================");
348 props.dispatch({ 348 props.dispatch({
349 type: "app/createWebSocket", 349 type: "app/createWebSocket",
350 payload: { reStart: true, dispatch: props.dispatch } 350 payload: { reStart: true, dispatch: props.dispatch }
@@ -352,15 +352,7 @@ const useIndexMesEvent = props => { @@ -352,15 +352,7 @@ const useIndexMesEvent = props => {
352 return; 352 return;
353 } 353 }
354 if (wsRef.current.readyState !== WebSocket.OPEN) return; 354 if (wsRef.current.readyState !== WebSocket.OPEN) return;
355 - const message = {  
356 - connectTest: 'test',  
357 - key: 'test',  
358 - flag: 'test',  
359 - msg: 'test',  
360 - sId: 'test',  
361 - showType: 'test',  
362 - sendFrom: props.app.userinfo.sId,  
363 - }; 355 + const message = { flag: "connectTest", sId: "test", sendFrom: userinfo.sId };
364 wsRef.current.send(JSON.stringify(message)); 356 wsRef.current.send(JSON.stringify(message));
365 window.wsTimer = setTimeout(() => { 357 window.wsTimer = setTimeout(() => {
366 console.log("================未收到Test返回消息,webSocket重新连接======================"); 358 console.log("================未收到Test返回消息,webSocket重新连接======================");
src/models/app.js
@@ -577,44 +577,114 @@ export default { @@ -577,44 +577,114 @@ export default {
577 if (userinfo.sUserLoginType) { 577 if (userinfo.sUserLoginType) {
578 url = `${config.ws_host}websocket/${userinfo.sId}?sLoginType=${userinfo.sUserLoginType}`; 578 url = `${config.ws_host}websocket/${userinfo.sId}?sLoginType=${userinfo.sUserLoginType}`;
579 } 579 }
580 - if (reStart) { 580 + if (true) {
581 // const webSocket = yield select(state => state.app.webSocket); 581 // const webSocket = yield select(state => state.app.webSocket);
582 // if (webSocket === null) { 582 // if (webSocket === null) {
583 // return null; 583 // return null;
584 // } 584 // }
585 - url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true`; 585 + url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&createTime=${new Date().getTime()}`;
586 if (userinfo.sUserLoginType) { 586 if (userinfo.sUserLoginType) {
587 url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&createTime=${new Date().getTime()}&sLoginType=${userinfo.sUserLoginType}`; 587 url = `${config.ws_host}websocket/${userinfo.sId}?reStart=true&createTime=${new Date().getTime()}&sLoginType=${userinfo.sUserLoginType}`;
588 } 588 }
589 } 589 }
  590 + // 清理旧的WebSocket连接和定时器
  591 + let oldWebSocket = yield select(state => state.app.webSocket);
  592 + if (oldWebSocket) {
  593 + // console.log('发现旧的WebSocket连接,准备清理:', oldWebSocket);
  594 + // console.log('旧WebSocket连接状态:', oldWebSocket.readyState);
  595 + try {
  596 + // 移除所有事件监听器
  597 + oldWebSocket.onopen = null;
  598 + oldWebSocket.onclose = null;
  599 + oldWebSocket.onerror = null;
  600 + oldWebSocket.onmessage = null;
  601 + oldWebSocket.onmessageTmp = null;
  602 + oldWebSocket.homeAction = null;
  603 +
  604 + // 关闭连接
  605 + if (oldWebSocket.readyState === WebSocket.OPEN || oldWebSocket.readyState === WebSocket.CONNECTING) {
  606 + oldWebSocket.close(1000, '正常关闭,准备重连');
  607 + // console.log('已关闭旧的WebSocket连接');
  608 + }
  609 + // 断开引用,帮助垃圾回收
  610 + oldWebSocket = null;
  611 + console.log('旧WebSocket连接已彻底清理');
  612 + } catch (error) {
  613 + console.log('关闭旧WebSocket连接时出错:', error);
  614 + }
  615 + } else {
  616 + console.log('没有发现旧的WebSocket连接');
  617 + }
  618 +
  619 + // 清除所有定时器
  620 + clearTimeout(window.wsTimer);
  621 + clearTimeout(config.timerServer);
  622 + clearTimeout(config.serverTimer);
  623 + window.wsTimer = null;
  624 + config.timerServer = null;
  625 + config.serverTimer = null;
  626 +
  627 + // 清理全局变量
  628 + window.wsHistoryArgs = undefined;
  629 + window.onmessageTmp = undefined;
590 const reset = (ws, config1) => { 630 const reset = (ws, config1) => {
591 clearTimeout(config1.timerServer); 631 clearTimeout(config1.timerServer);
592 clearTimeout(config1.serverTimer); 632 clearTimeout(config1.serverTimer);
593 start(ws, config1); 633 start(ws, config1);
594 }; 634 };
595 const start = (ws, config1) => { 635 const start = (ws, config1) => {
  636 + if (!ws.originalSend) {
  637 + ws.originalSend = ws.send.bind(ws);
  638 + }
  639 + ws.send = (...args) => {
  640 + const value = utils.convertStrToObj(args[0], {});
  641 + const {
  642 + key,
  643 + flag,
  644 + sendFrom,
  645 + sId,
  646 + } = value;
  647 + if ((key && flag && !['release', 'noAction'].includes(flag) && sendFrom && sId) || flag === 'connectTest') {
  648 + // 3s内没返回消息,则重新创建ws,重新发送
  649 + clearTimeout(window.wsTimer);
  650 + window.wsTimer = setTimeout(() => {
  651 + // 检查当前WebSocket连接状态
  652 + if (ws && ws.readyState === WebSocket.OPEN) {
  653 + console.log('================WebSocket连接正常但超时未收到消息,重新发送信息======================');
  654 + // 先尝试重新发送消息,而不是直接创建新连接
  655 + ws.originalSend.apply(ws, args);
  656 + } else {
  657 + console.log('================超时未收到WebSocket消息,重新创建ws并发送信息======================');
  658 + window.wsHistoryArgs = args;
  659 + ws.onmessageTmp && (window.onmessageTmp = ws.onmessageTmp);
  660 + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } });
  661 + }
  662 + }, 3000);
  663 + }
  664 + ws.originalSend.apply(ws, args);
  665 + };
  666 +
  667 + if (window.wsHistoryArgs) {
  668 + ws.send(...window.wsHistoryArgs);
  669 + window.wsHistoryArgs = undefined;
  670 + }
  671 + if (window.onmessageTmp) {
  672 + ws.onmessageTmp = window.onmessageTmp;
  673 + window.onmessageTmp = undefined;
  674 + }
  675 + clearTimeout(config1.timerServer);
596 config1.timerServer = setTimeout(() => { 676 config1.timerServer = setTimeout(() => {
597 const message = { sendFrom: userinfo.sId, connectTest: 'test' }; // param 存放其它参数 keyName 需要放入Redis的数据key,keyValue 需要放入Redis的数据key 的值 677 const message = { sendFrom: userinfo.sId, connectTest: 'test' }; // param 存放其它参数 keyName 需要放入Redis的数据key,keyValue 需要放入Redis的数据key 的值
598 ws.send(JSON.stringify(message)); 678 ws.send(JSON.stringify(message));
599 }, config1.timeoutServer); 679 }, config1.timeoutServer);
600 }; 680 };
601 - const oldWebSocket = yield select(state => state.app.webSocket);  
602 const ws = new WebSocket(url); 681 const ws = new WebSocket(url);
603 ws.onopen = function (e) { 682 ws.onopen = function (e) {
604 console.log('连接上 webscoket 服务端了', e); 683 console.log('连接上 webscoket 服务端了', e);
605 start(ws, config); 684 start(ws, config);
606 - if (oldWebSocket && oldWebSocket !== ws) {  
607 - try {  
608 - oldWebSocket.close();  
609 - console.log('================已关闭旧的WebSocket连接======================');  
610 - } catch (error) {  
611 - console.log('================关闭旧WebSocket连接时出错======================', error);  
612 - }  
613 - }  
614 }; 685 };
615 // 全局通用的自定义onmessage的方法 686 // 全局通用的自定义onmessage的方法
616 - ws.homeAction = (msg) => {  
617 - clearTimeout(window.wsTimer); 687 + ws.homeAction = msg => {
618 const rtmsg = JSON.parse(msg.data); 688 const rtmsg = JSON.parse(msg.data);
619 if (false && rtmsg.action === 'showImg' && location.pathname.indexOf('/indexOee') < 0) { 689 if (false && rtmsg.action === 'showImg' && location.pathname.indexOf('/indexOee') < 0) {
620 const msgData = JSON.parse(msg.data); 690 const msgData = JSON.parse(msg.data);
@@ -678,16 +748,49 @@ export default { @@ -678,16 +748,49 @@ export default {
678 } 748 }
679 }; 749 };
680 ws.onmessage = (msg) => { 750 ws.onmessage = (msg) => {
  751 + clearTimeout(window.wsTimer);
  752 + window.xlyWsTimerFun && window.xlyWsTimerFun();
681 reset(ws, config); 753 reset(ws, config);
  754 + ws.onmessageTmp?.(msg);
682 ws.homeAction(msg); 755 ws.homeAction(msg);
683 }; 756 };
684 ws.onclose = (e) => { 757 ws.onclose = (e) => {
685 /* 当客户端收到服务器端发送关闭请求,触发onclose事件 */ 758 /* 当客户端收到服务器端发送关闭请求,触发onclose事件 */
686 console.log('webscoket关闭!!', e); 759 console.log('webscoket关闭!!', e);
  760 + // 清理定时器
  761 + clearTimeout(window.wsTimer);
  762 + clearTimeout(config.timerServer);
  763 + clearTimeout(config.serverTimer);
  764 + window.wsTimer = null;
  765 + config.timerServer = null;
  766 + config.serverTimer = null;
  767 +
  768 +
  769 + // 自动重连
  770 + if (e.code !== 1000) { // 非正常关闭
  771 + console.log('WebSocket非正常关闭,将在5秒后尝试重连');
  772 + setTimeout(() => {
  773 + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } });
  774 + }, 5000);
  775 + }
687 }; 776 };
688 ws.onerror = (e) => { 777 ws.onerror = (e) => {
689 /* 如果出现连接、处理、接收、发送数据异常 触发onerror */ 778 /* 如果出现连接、处理、接收、发送数据异常 触发onerror */
690 console.log('webscoket异常!!', e); 779 console.log('webscoket异常!!', e);
  780 + // 清理定时器
  781 + clearTimeout(window.wsTimer);
  782 + clearTimeout(config.timerServer);
  783 + clearTimeout(config.serverTimer);
  784 + window.wsTimer = null;
  785 + config.timerServer = null;
  786 + config.serverTimer = null;
  787 +
  788 +
  789 + // 自动重连
  790 + console.log('WebSocket出现异常,将在5秒后尝试重连');
  791 + setTimeout(() => {
  792 + dispatch({ type: 'app/createWebSocket', payload: { reStart: true, dispatch } });
  793 + }, 5000);
691 }; 794 };
692 yield put({ type: 'saveWebSocket', payload: { webSocket: ws } }); 795 yield put({ type: 'saveWebSocket', payload: { webSocket: ws } });
693 }, 796 },