前端websocket连接

class WebSocketHeart {
  constructor({ url, pingTimeout, pongTimeout, reconnectTimeout, pingMsg }) {
    this.url = url; // websocket服务端接口地址
    this.pingTimeout = pingTimeout || 30000; // 每隔 30 秒发送一次心跳,如果收到任何后端消息定时器将会重置
    this.pongTimeout = pongTimeout || 10000; // ping 消息发送之后,10 秒内没收到后端消息便会认为连接断开
    this.reconnectTimeout = reconnectTimeout || 30000; // 尝试重连的间隔时间
    this.pingMsg = pingMsg || '{"code":"0000","data":"heart check"}'; // 发送心跳消息
    this.ws = null; // websocket 实例

    // 回调钩子
    this.onclose = () => {};
    this.onerror = () => {};
    this.onopen = () => {};
    this.onmessage = () => {};
    this.onreconnect = () => {};

    this.createWebSocket();
  }

  // 创建 WebSocket 实例
  createWebSocket() {
    try {
      this.ws = new WebSocket(this.url);
      this.initEventHandle();
    } catch (e) {
      this.reconnect();
      throw e;
    }
  }

  // 初始化事件钩子
  initEventHandle() {
    this.ws.onclose = () => {
      this.onclose();
      this.reconnect();
    };
    this.ws.onerror = () => {
      console.log('err');
      this.onerror();
      this.reconnect();
    };
    this.ws.onopen = () => {
      this.onopen();
      //心跳检测重置
      this.heartCheck();
    };
    this.ws.onmessage = event => {
      this.onmessage(event);
      //如果获取到消息,心跳检测重置
      //拿到任何消息都说明当前连接是正常的
      this.heartCheck();
    };
  }

  // 重连
  reconnect() {
    if (this.lockReconnect || this.forbidReconnect) return;
    this.lockReconnect = true;
    this.onreconnect();
    //没连接上会一直重连,设置延迟避免请求过多
    setTimeout(() => {
      this.createWebSocket();
      this.lockReconnect = false;
    }, this.reconnectTimeout);
  }

  // 发送消息
  send(msg) {
    this.ws.send(msg);
  }

  // 心态检测
  heartCheck() {
    console.log(this.url, 'ws心跳检测');
    this.heartReset();
    this.heartStart();
  }

  // 心态重置
  heartReset() {
    clearTimeout(this.pingTimeoutId);
    clearTimeout(this.pongTimeoutId);
  }

  // 发送心跳
  heartStart() {
    if (this.forbidReconnect) return; //不再重连就不再执行心跳
    this.pingTimeoutId = setTimeout(() => {
      //这里发送一个心跳,后端收到后,返回一个心跳消息,
      // onmessage 拿到返回的心跳就说明连接正常
      this.ws.send(this.pingMsg);
      //如果超过一定时间还没重置,说明后端主动断开了
      this.pongTimeoutId = setTimeout(() => {
        //如果 onclose 会执行 reconnect,我们执行 ws.close() 就行了.如果直接执行 reconnect 会触发 onclose 导致重连两次
        // this.ws.close();
      }, this.pongTimeout);
    }, this.pingTimeout);
  }

  // 手动关闭
  close() {
    //如果手动关闭连接,不再重连
    console.log('关闭ws连接');
    this.forbidReconnect = true;
    this.heartReset();
    this.ws.close();
  }
}

export { WebSocketHeart };

在vue页面中进行调用

const onConnSocketProjection = () => {
  const url = 'ws://10.10.9.76:17002/api/websocket/10';
  let projectionWS = new WebSocketHeart({
    url,
    pingMsg: '{"type":"0000","data":"heart check"}',
  });
  projectionWS.onopen = function () {
    console.log('Connection open ...');
    projectionWS.send('Hello WebSockets!');
  };
  projectionWS.onmessage = async evt => {
    console.log('evt.data', evt.data);
    ElMessage({
      type: 'warning',
      message: '电表设备异常',
    });
    await getAirWaterPage();
    getDeviceStatus();
  };
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值