心跳机制

2021-11-12  本文已影响0人  zhenghongmo
 useEffect(() => {
    //避免重复链接
    let lockReconnect = false;
    //路径
    let wsUrl = `ws://xxx.yyy.com/imserver/xxx`
    //webSocket对象
    let ws;
    //时间间隔
    let tt;

    // if ("WebSocket" in window) {
    //     console.log("支持WebSocket")
    // } else {
    //     alert("该浏览器不支持WebSocket")
    // }

    //创建ws连接
    let createWebSocket = function (wsUrl) {
      try {
        //成功
        ws = new WebSocket(wsUrl);
        webSocketInit(); //初始化webSocket连接函数
      } catch (e) {
        // console.log('catch');
        //重连函数
        webSocketReconnect(wsUrl);
      }
    };
    //初始化方法,成功后执行
    let webSocketInit = function () {
      //连接关闭函数
      ws.onclose = function () {
        // console.log("连接已关闭...");
        webSocketReconnect(wsUrl); //如果连接关闭则重连
      };
      //连接错误函数
      ws.onerror = function () {
        // console.log("连接错误...");
        webSocketReconnect(wsUrl); //如果连接错误则重连
      };
      //连接建立,发送信息
      ws.onopen = function () {
        ws.send(JSON.stringify(''));
        //心跳检测启动
        heartCheck.start(); //订阅业务发送之后启动心跳检测机制
      };
      //业务订阅成功后接受服务端推送消息  ,其实是个字符串
      ws.onmessage = function (event) {
        // console.log('success=>', JSON.parse(event.data));
        let eventData = JSON.parse(event.data);
        //-----此处对返回数据进行处理----
        heartCheck.reset();
      };
    };

    let webSocketReconnect = function (url) {
      // console.log("socket 连接断开,正在尝试重新建立连接");
      if (lockReconnect) {
        return;
      }
      lockReconnect = true;
      //没连接上会一直重连,设置延迟,避免请求过多
      //s中清楚setTimeout的定时触发设置,之所以加个timer,是为了方便第二次赋值给timer。
      // 也就是说直接clearTImeout(timer)则timer就不存在了 再次访问就是error了。
      // 而timer&&clearTimeout(timer)则将timer 变成undefined
      tt && clearTimeout(tt);
      tt = setTimeout(function () {
        createWebSocket(url);
      }, 4000);
    };

    //心跳检测.所谓的心跳检测,就是隔一段时间向服务器仅限一次数据访问,因为长时间不使用会导致ws自动断开,
    // 一般是间隔90秒内无操作会自动断开,因此,在间隔时间内进行一次数据访问,以防止ws断开即可,
    //这里选择30秒,倒计时30秒内无操作则进行一次访问,有操作则重置计时器
    var heartCheck = {
      timeout: 30000, //30秒
      timeoutObj: null,
      reset: function () {
        //接收成功一次推送,就将心跳检测的倒计时重置为30秒
        clearTimeout(this.timeoutObj); //重置倒计时
        this.start();
      },
      start: function () {
        //启动心跳检测机制,设置倒计时30秒一次
        this.timeoutObj = setTimeout(function () {
          // console.log("心跳一次");
          ws.send('ping'); //启动心跳
        }, this.timeout);
      },
      //onopen连接上,就开始start及时,如果在定时时间范围内,onmessage获取到了服务端消息,
      // 就重置reset倒计时,距离上次从后端获取消息30秒后,执行心跳检测,看是不是断了。
    };

    //开始创建webSocket连接
    createWebSocket(wsUrl);
    return () => {
      ws.close();
    };
  }, []);
上一篇下一篇

猜你喜欢

热点阅读