兰宝车间质量管理系统-前端
疯狂的狮子Li
2025-01-20 5e440a7dc434c43eb828fa62cf9c12b0078b8565
src/utils/websocket.ts
@@ -1,141 +1,51 @@
/**
 * @module initWebSocket 初始化
 * @module websocketonopen 连接成功
 * @module websocketonerror 连接失败
 * @module websocketclose 断开连接
 * @module resetHeart 重置心跳
 * @module sendSocketHeart 心跳发送
 * @module reconnect 重连
 * @module sendMsg 发送数据
 * @module websocketonmessage 接收数据
 * @module test 测试收到消息传递
 * @description socket 通信
 * @param {any} url socket地址
 * @param {any} websocket websocket 实例
 * @param {any} heartTime 心跳定时器实例
 * @param {number} socketHeart 心跳次数
 * @param {number} HeartTimeOut 心跳超时时间
 * @param {number} socketError 错误次数
 */
import { getToken } from '@/utils/auth';
import useNoticeStore from '@/store/modules/notice';
import { ElNotification } from 'element-plus';
const { addNotice } = useNoticeStore();
let socketUrl: any = ''; // socket地址
let websocket: any = null; // websocket 实例
let heartTime: any = null; // 心跳定时器实例
let socketHeart = 0 as number; // 心跳次数
const HeartTimeOut = 10000; // 心跳超时时间 10000 = 10s
let socketError = 0 as number; // 错误次数
import useNoticeStore from '@/store/modules/notice';
// 初始化socket
export const initWebSocket = (url: any) => {
  if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
    return;
  }
  socketUrl = url;
  // 初始化 websocket
  websocket = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID);
  websocketonopen();
  websocketonmessage();
  websocketonerror();
  websocketclose();
  sendSocketHeart();
  return websocket;
};
// socket 连接成功
export const websocketonopen = () => {
  websocket.onopen = function () {
    console.log('连接 websocket 成功');
    resetHeart();
  };
};
// socket 连接失败
export const websocketonerror = () => {
  websocket.onerror = function (e: any) {
    console.log('连接 websocket 失败', e);
  };
};
// socket 断开链接
export const websocketclose = () => {
  websocket.onclose = function (e: any) {
    console.log('断开连接', e);
  };
};
// socket 重置心跳
export const resetHeart = () => {
  socketHeart = 0;
  socketError = 0;
  clearInterval(heartTime);
  sendSocketHeart();
};
// socket心跳发送
export const sendSocketHeart = () => {
  heartTime = setInterval(() => {
    // 如果连接正常则发送心跳
    if (websocket.readyState == 1) {
      // if (socketHeart <= 30) {
      websocket.send(
        JSON.stringify({
          type: 'ping'
        })
      );
      socketHeart = socketHeart + 1;
    } else {
      // 重连
      reconnect();
  url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID;
  useWebSocket(url, {
    autoReconnect: {
      // 重连最大次数
      retries: 3,
      // 重连间隔
      delay: 1000,
      onFailed() {
        console.log('websocket重连失败');
      }
    },
    heartbeat: {
      message: JSON.stringify({ type: 'ping' }),
      // 发送心跳的间隔
      interval: 10000,
      // 接收到心跳response的超时时间
      pongTimeout: 2000
    },
    onConnected() {
      console.log('websocket已经连接');
    },
    onDisconnected() {
      console.log('websocket已经断开');
    },
    onMessage: (_, e) => {
      if (e.data.indexOf('ping') > 0) {
        return;
      }
      useNoticeStore().addNotice({
        message: e.data,
        read: false,
        time: new Date().toLocaleString()
      });
      ElNotification({
        title: '消息',
        message: e.data,
        type: 'success',
        duration: 3000
      });
    }
  }, HeartTimeOut);
};
// socket重连
export const reconnect = () => {
  if (socketError <= 2) {
    clearInterval(heartTime);
    initWebSocket(socketUrl);
    socketError = socketError + 1;
    // eslint-disable-next-line prettier/prettier
    console.log('socket重连', socketError);
  } else {
    // eslint-disable-next-line prettier/prettier
    console.log('重试次数已用完');
    clearInterval(heartTime);
  }
};
// socket 发送数据
export const sendMsg = (data: any) => {
  websocket.send(data);
};
// socket 接收数据
export const websocketonmessage = () => {
  websocket.onmessage = function (e: any) {
    if (e.data.indexOf('heartbeat') > 0) {
      resetHeart();
    }
    if (e.data.indexOf('ping') > 0) {
      return;
    }
    addNotice({
      message: e.data,
      read: false,
      time: new Date().toLocaleString()
    });
    ElNotification({
      title: '消息',
      message: e.data,
      type: 'success',
      duration: 3000
    });
    return e.data;
  };
  });
};