WebSocket封装方案

发布于:2024-07-01 ⋅ 阅读:(11) ⋅ 点赞:(0)

ws.js

export default class WS {
  options = {};
  ws = null;
  heartBeatCount = 0;
  heartInterval = null;

  constructor({
    url,
    maxHeartCount = 3,
    loopCheckTime = 30000,
    initConnectCb,
    getMessageCb,
    errorCb,
    closeCb,
    heartInfo
  }) {
    this.options = {
      url,
      maxHeartCount,
      loopCheckTime,
      initConnectCb,
      getMessageCb,
      errorCb,
      closeCb,
      sso_session_id2: localStorage.getItem('sso_session_id2'),
      heartInfo: JSON.stringify(heartInfo)
    };
  }
  
  /**开启wbsocket */
  startWs() {
    if (this.ws) {
      return;
    }
    this.connect();
    this.errorHandle();
    this.getMessage();
    this.closeHandle();
  }

  /**
   * 手动关闭连接
   * */
  closeWs() {
    this.consoleLog('websocket----:手动关闭websocket');
    if (this.heartInterval) {
      clearInterval(this.heartInterval);
    }
    this.ws.close();
    this.ws = null;
  }

  /**
   * 连接websocket
   * */
  connect() {
    this.heartBeatCount = 0;
    this.ws = new WebSocket(`${this.options.url}`);
    this.ws.onopen = () => {
      this.consoleLog('websocket----:websocket建立连接');
      this.heartCheck();
      if (this.options.initConnectCb) {
        this.consoleLog('websocket----:初始化发送消息');
        this.options.initConnectCb();
      }
    };
  }

  /**
   * 开启检测
   * */
  heartCheck() {
    if (!this.options.heartInfo) return;

    let that = this;
    this.ws.send(this.options.heartInfo);
    this.heartInterval = setInterval(() => {
      this.consoleLog(this.ws.readyState);
      if (this.ws.readyState === 1) {
        this.heartBeatCount += 1;
        if (this.heartBeatCount <= this.options.maxHeartCount) {
          that.ws.send(that.options.heartInfo);
          this.consoleLog(`websocket----:第${this.heartBeatCount}次检测心跳`);
        } else {
          this.consoleLog(
            `websocket----:第${this.heartBeatCount}次检测心跳,心跳检测超出最大检测次数,启动重连程序`
          );
          this.reConnect();
        }
      } else {
        this.consoleLog(
          `websocket----:第${this.heartBeatCount}次检测心跳,连接建立失败,启动重连程序`
        );
        this.reConnect();
      }
    }, this.options.loopCheckTime);
  }

  /**
   * 获取消息
   * */
  getMessage() {
    this.ws.onmessage = (e) => {
      this.consoleLog('websocket----:接收到websocket的消息触发回调');
      if (e.data) {
        try {
          const data = JSON.parse(e.data);
          if (
            (data.header && data.header.type === 'HEART') ||
            data == this.options.heartInfo
          ) {
            this.consoleLog(
              'websocket----:接受心跳检测成功响应,心跳检测次数重置为0'
            );
            this.heartBeatCount = 0;
          } else {
            this.consoleLog('业务数据获取:', data);
            if (this.options.getMessageCb) {
              this.options.getMessageCb(data);
            }
          }
        } catch (e) {
          this.consoleLog(e);
        }
      }
    };
  }

  /**
   * 通信错误触发
   * */
  errorHandle() {
    this.ws.onerror = (e) => {
      this.consoleLog('websocket----:websocket通信发生错误触发回调:', e);
      if (this.options.errorCb) {
        this.options.errorCb(e);
      }
      this.reConnect();
    };
  }

  /**
   * 关闭时触发
   * */
  closeHandle() {
    this.ws.onclose = (e) => {
      this.consoleLog('websocket----:websocket关闭触发回调', e);

      if (this.options.closeCb) {
        this.options.closeCb(e);
      }
    };
  }

  /**
   * 启动重连程序
   * */
  reConnect() {
    this.consoleLog('websocket----:启动重新连接');
    if (this.heartInterval) {
      clearInterval(this.heartInterval);
    }
    this.closeWs();
    this.connect();
  }

  consoleLog() {
    // console.log(...arguments);
  }
}

use

import WS from "@/utils/ws";

const url = `ws://${ip}:12220/command/webSocket/${userId}`;
const ws = new WS({
  url,
  heartInfo: "heart",
  getMessageCb: (data) => {
    unread.value = data ? Number(data) : null;
  },
});
ws.startWs();


网站公告

今日签到

点亮在社区的每一天
去签到