websocket連線

南瓜壳發表於2024-08-15

https://blog.csdn.net/qq_70071513/article/details/133171580

//暴露自定義websocket物件
export const socket = {
  //後臺請求路徑
  url: "",
  //websocket物件
  websocket: null,
  //websocket狀態
  websocketState: false,
  //重新連線次數
  reconnectNum: 0,
  //重連鎖狀態,保證重連按順序執行
  lockReconnect: false,
  //定時器資訊
  timeout: null,
  clientTimeout: null,
  serverTimeout: null,
  //初始化方法,根據url建立websocket物件封裝基本連線方法,並重置心跳檢測
  initWebSocket(newUrl) {
    socket.url = newUrl;
    socket.websocket = new WebSocket(socket.url);
    socket.websocket.onopen = socket.websocketOnOpen;
    socket.websocket.onerror = socket.websocketOnError;
    socket.websocket.onclose = socket.websocketOnClose;
    this.resetHeartbeat()
  },
  reconnect() {
    //判斷連線狀態
    if (socket.lockReconnect) return;
    socket.reconnectNum += 1;
    //重新連線三次還未成功呼叫連線關閉方法
    if (socket.reconnectNum === 3) {
      socket.reconnectNum = 0;
      socket.websocket.onclose()
      return;
    }
    //等待本次重連完成後再進行下一次
    socket.lockReconnect = true;
    //5s後進行重新連線
    socket.timeout = setTimeout(() => {
      socket.initWebSocket(socket.url);
      socket.lockReconnect = false;
    }, 5000);
  },
  //重置心跳檢測
  resetHeartbeat() {
    socket.heartbeat();
  },
  //心跳檢測
  heartbeat() {
    socket.clientTimeout = setTimeout(() => {
      if (socket.websocket) {
        //向後臺傳送訊息進行心跳檢測
        socket.websocket.send(JSON.stringify({ type: "heartbeat" }));
        socket.websocketState = false;
        //一分鐘內伺服器不響應則關閉連線
        socket.serverTimeout = setTimeout(() => {
          if (!socket.websocketState) {
            socket.websocket.onclose()
          } else {
            this.resetHeartbeat()
          }
        }, 60 * 1000);
      }
    }, 3 * 1000);
  },
  //傳送訊息
  sendMsg(message) {
    socket.websocket.send(JSON.stringify({ type: "message", message: message}));
  },
  websocketOnOpen(event) {
    //連線開啟後向後臺傳送訊息進行一次心跳檢測
    socket.websocket.send(JSON.stringify({ type: "heartbeat" }));
  },
  websocketOnError(error) {
    console.log(error);
    socket.reconnect();
  },
  websocketOnClose() {
    socket.websocket.close();
  },
};

2.引入websocket.js

//引入socket物件
import { socket } from "@/utils/websocket";

3.使用

created() {
    this.getMessageNumber()
    //初始化websocket物件
    socket.initWebSocket(process.env.VUE_APP_BASE_WS + "/" + window.localStorage.getItem("webSocketKey"));
    //繫結接收訊息方法
    socket.websocket.onmessage = this.websocketOnMessage;
  },
  beforeDestroy() {
    // 元件銷燬時關閉連結釋放資源
    socket.websocketOnClose()
  },
  methods: {
    /** 初始化連線測試*/
    init() {
      socket.websocketOnOpen();
    },

    /** 接收websocket訊息*/
    websocketOnMessage(event) {
      //初始化介面時,會主動向後臺傳送一次訊息,獲取資料
      this.websocketCount += 1;

      //沒有傳送成功則重新初始化一次
      if (this.websocketCount === 0) {
        this.init();
      }
      let info = JSON.parse(event.data);
      switch (info.type) {
        case "heartbeat":
          socket.websocketState = true;
          break;
        case "message":
          this.loading = true;
          this.$nextTick(() => {
            // 收到文字訊息
            this.consumeTextMessage(info)
            
            //收到檔案訊息
            //this.consumeFileMessage(info);
          })
          break;
        case "error":
          this.loading = false;
          break;
      }
    },

    /** 處理推送的文字資料 */
    consumeTextMessage(info) {
      const h = this.$createElement;
      this.$notify({
        title: '新的通知',
        message: h('i', { style: 'color: teal'}, info.message)
      });
    },

    /** 處理推送的檔案資料 這裡傳送的是xlsx檔案,可根據需求自定義,也可以將檔名一起從後端傳過來 */
    consumeFileMessage(info) {
      let infoObj = info
      //伺服器向客戶端推送檔案  生成檔案
      Base64StrToFileUtil.downloadFileByBase64(infoObj.message, "01.xlsx")
    }
  }

  

相關文章