Commit a13a0b0e613c4c1db199cb0613b9334c55a92648

Authored by Min
1 parent f7ff6604

1.修改ws重连逻辑

src/mes/indexMes/index.js
... ... @@ -332,7 +332,7 @@ const useIndexMesEvent = props => {
332 332 [currentContent, sModelsId, sModelType]
333 333 );
334 334  
335   - const { webSocket: ws } = props.app;
  335 + const { webSocket: ws, userinfo } = props.app;
336 336 const { url } = ws || {};
337 337 const wsRef = useRef(ws);
338 338 useEffect(() => {
... ... @@ -343,8 +343,8 @@ const useIndexMesEvent = props => {
343 343  
344 344 useEffect(() => {
345 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 348 props.dispatch({
349 349 type: "app/createWebSocket",
350 350 payload: { reStart: true, dispatch: props.dispatch }
... ... @@ -352,15 +352,7 @@ const useIndexMesEvent = props => {
352 352 return;
353 353 }
354 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 356 wsRef.current.send(JSON.stringify(message));
365 357 window.wsTimer = setTimeout(() => {
366 358 console.log("================未收到Test返回消息,webSocket重新连接======================");
... ...
src/models/app.js
... ... @@ -577,44 +577,114 @@ export default {
577 577 if (userinfo.sUserLoginType) {
578 578 url = `${config.ws_host}websocket/${userinfo.sId}?sLoginType=${userinfo.sUserLoginType}`;
579 579 }
580   - if (reStart) {
  580 + if (true) {
581 581 // const webSocket = yield select(state => state.app.webSocket);
582 582 // if (webSocket === null) {
583 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 586 if (userinfo.sUserLoginType) {
587 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 630 const reset = (ws, config1) => {
591 631 clearTimeout(config1.timerServer);
592 632 clearTimeout(config1.serverTimer);
593 633 start(ws, config1);
594 634 };
595 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 676 config1.timerServer = setTimeout(() => {
597 677 const message = { sendFrom: userinfo.sId, connectTest: 'test' }; // param 存放其它参数 keyName 需要放入Redis的数据key,keyValue 需要放入Redis的数据key 的值
598 678 ws.send(JSON.stringify(message));
599 679 }, config1.timeoutServer);
600 680 };
601   - const oldWebSocket = yield select(state => state.app.webSocket);
602 681 const ws = new WebSocket(url);
603 682 ws.onopen = function (e) {
604 683 console.log('连接上 webscoket 服务端了', e);
605 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 686 // 全局通用的自定义onmessage的方法
616   - ws.homeAction = (msg) => {
617   - clearTimeout(window.wsTimer);
  687 + ws.homeAction = msg => {
618 688 const rtmsg = JSON.parse(msg.data);
619 689 if (false && rtmsg.action === 'showImg' && location.pathname.indexOf('/indexOee') < 0) {
620 690 const msgData = JSON.parse(msg.data);
... ... @@ -678,16 +748,49 @@ export default {
678 748 }
679 749 };
680 750 ws.onmessage = (msg) => {
  751 + clearTimeout(window.wsTimer);
  752 + window.xlyWsTimerFun && window.xlyWsTimerFun();
681 753 reset(ws, config);
  754 + ws.onmessageTmp?.(msg);
682 755 ws.homeAction(msg);
683 756 };
684 757 ws.onclose = (e) => {
685 758 /* 当客户端收到服务器端发送关闭请求,触发onclose事件 */
686 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 777 ws.onerror = (e) => {
689 778 /* 如果出现连接、处理、接收、发送数据异常 触发onerror */
690 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 795 yield put({ type: 'saveWebSocket', payload: { webSocket: ws } });
693 796 },
... ...