记一次websocket重连机制

做websocket链接的时候不得不考虑的情况就是断线重连的情况,在一个websocket被建立之后若服务端的程序出故障了,这个websocket连接将处于一种未知的状态。
为了避免这种情况的出现:我们通常用心跳信息来保证连接的存活:
在Vue中的代码如下:

methods: {
    initWebSocket () {
      let that = this
      if (this.ws) {
        this.ws.close()
        delete this.ws
      }
      that.subSysSockt = new WebSocket(airWsuri)
      that.subSysSockt.onopen = this.openWs
      that.subSysSockt.onmessage = this.reviceMsg
      // 这里的onerror只有在前端websocket发生异常时才会触发
      that.subSysSockt.onerror = this.wserr
      // 这里的onclose只有在前端主动关闭websocket时才会触发
      that.subSysSockt.onclose = this.reConnect
      that.timer = setInterval(() => {
        if (that.subSysSockt.readyState === 1) {
          /*
            重连的思路: 每次前端往后端发送心跳信息,若心跳信息发出去2秒钟后未收到后端的回应
            则关闭这个websocket连接,重新建立websocket链接
          */
          that.subSysSockt.send("test")
          // 这个waitMsg用于判断是否收到服务端回的心跳信息
          this.waitMsg = false
          that.timerWait = setTimeout(() => {
            if (that.waitMsg === false) {
              console.log('重连websocket...')
              clearInterval(that.timer)
              clearTimeout(that.timerWait)
              that.subSysSockt.close()
              that.initWebSocket()
            } else {
              clearTimeout(that.timerWait)
            }
          }, 2000)
        }
      }, 20000)
    },
    reviceMsg (event) {
      // 收到消息时标志置为true
      this.waitMsg = true
      clearTimeout(this.timerWait)
      try {
        let message = JSON.parse(event.data)
        // 2020-6-22 临时解决方法(deviceType为2006和2008的设备就是要显示的设备)
        this.device = message.deviceNumInfoList.filter(e => e.deviceType === 2006 || e.deviceType === 2008)
      } catch (e) {
        // replay异常暂时不处理...
      }
    },
    openWs () {
      if (this.subSysSockt.readyState === 1) {
        let that = this
        let subscribeSys = {
          "system_id": 1000
        }
        // 获取报警视频列表
        that.subSysSockt.send(JSON.stringify(subscribeSys))
      }
    },
    reConnect () {
      let self = this
      this.timer2 = setInterval(() => {
        if (self.subSysSockt.readyState === 3) {
          self.subSysSockt = new WebSocket(airWsuri)
          clearInterval(this.timer2)
        }
      }, 2000)
    },
  ......
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。