websocket 断开重连机制(心跳机制)

一、何为心跳?

心跳就是客户端定时的给服务端发送消息,证明客户端是在线的, 如果超过一定的时间没有发送则就是离线了。

二、如何判断在线离线?

当客户端第一次发送请求至服务端时会携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果不存在就存入db或者缓存中,

第二次客户端定时再次发送请求依旧携带唯一标识、以及时间戳,服务端到db或者缓存去查询改请求的唯一标识,如果存在就把上次的时间戳拿取出来,使用当前时间戳减去上次的时间,

得出的毫秒秒数判断是否大于指定的时间,若小于的话就是在线,否则就是离线;

三、若服务端宕机了,客户端怎么做、服务端再次上线时怎么做?

客户端则需要断开连接,通过onclose 关闭连接,服务端再次上线时则需要清除之间存的数据,若不清除 则会造成只要请求到服务端的都会被视为离线。

 具体代码如下:

      var socket; //websocket的实例
      var lockReconnect = false; //避免重复连接

      function getwebsocket() { //新建websocket的函数 页面初始化 断开连接时重新调用
          var wsUrl = 'ws://10.200.101.121:9001/websocket?wsToken=' + window.token + '&djxh=' + window.djxh;
          socket = new WebSocket(wsUrl);
          socket.onerror = function(event) {
              //console.log('websocket服务出错了');
              reconnect(wsUrl);
          };
          socket.onclose = function(event) {
              //console.log('websocket服务关闭了');
              reconnect(wsUrl);
          };
          socket.onopen = function(event) {
              heartCheck.reset().start(); //传递信息
          };
          socket.onmessage = function(event) {
              //如果获取到消息,心跳检测重置
              //拿到任何消息都说明当前连接是正常的
              //console.log('websocket服务获得数据了');
              //接受消息后的UI变化
              doWithMsg(event.data);
              heartCheck.reset().start();
          };
          //收到消息推送
          function doWithMsg(msg) {
              getdjxh() //这个函数是业务上面申请列表的函数 可以忽略
              window.external.CallFun('receiveMsg'); //这个也是
          }
      }
      // 重新链接
      function reconnect(url) {
          if (lockReconnect) return;
          lockReconnect = true;
          //没连接上会一直重连,设置延迟避免请求过多
          setTimeout(function() {
              getwebsocket();
              lockReconnect = false;
          }, 2000);
      }
      //心跳检测
      var heartCheck = {
          timeout: 60000, //60秒
          timeoutObj: null,
          serverTimeoutObj: null,
          reset: function() {
              clearTimeout(this.timeoutObj);
              clearTimeout(this.serverTimeoutObj);
              return this;
          },
          start: function() {
              var self = this;
              this.timeoutObj = setTimeout(function() {
                  //这里发送一个心跳,后端收到后,返回一个心跳消息,
                  //onmessage拿到返回的心跳就说明连接正常
                  socket.send("心跳测试");
                  //如果超过一定时间还没重置,说明后端主动断开了
                  self.serverTimeoutObj = setTimeout(function() {
                    //如果onclose会执行reconnect,我们执行ws.close()就行了.
                    //如果直接执行reconnect 会触发onclose导致重连两次
                    socket.close(); 
                  }, self.timeout)
              }, this.timeout)
          }
      }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值