zoukankan      html  css  js  c++  java
  • websocket 重连封装

    /**
     * websocket 类
     *
     * 回调方法和原生websocket保持一致
     * @param {String} url 连接地址
     * @param {Boolean} isReconnect 是否包含重连机制
     *    定时向后端发送 'ping' 后端收到后返回对应值,以此检测连接是否在线
     *    如不在线则定时发起重连
     * @param {Object} options 配置参数
     * **/
    class Ws {
      constructor(url, isReconnect = true, options = {}) {
        if (url) {
          if (typeof options === 'object') {
            this.opt = {
              url: url, // 连接地址
              // 心跳检测
              isReconnect: isReconnect, // 是否开启重连
              timeout: 4000, // 超时时间,超过后则发起重连
              pingString: 'ping', // 检测标识
              intervalStep: 3000, // 定时ping服务时间
              reconnectStep: 3000 // 设置重连间隔,防止重复连接
            }
            this.opt = {
              ...this.opt,
              ...options
            }
            this.lockReconnect = false // 重连锁,避免频繁重连
            this.isClose = false
            this.onopen = () => {} // 创建打开连接回调
            this.onmessage = () => {} // 收到消息通知的回调
            this.onclose = () => {} // 关闭连接的回调
            this.onerror = () => {} // 连接错误回调
            this.timeoutObj = null // 心跳检测计时器
            this.intervalObj = null // 定时发送计时器
            this.reconnectTimer = null // 避免重连锁
            this.createWs()
          } else {
            console.error('options need object')
          }
        } else {
          console.error('ur is required')
        }
      }
      // 创建ws
      createWs() {
        if (this.ws) {
          this.close()
        }
        this.ws = new WebSocket(this.opt.url)
        this.isClose = false
        this.setWsData()
        this.ws.onopen = () => {
          if (this.opt.isReconnect) {
            this.ping()
            this.reset().start()
          }
          this.onopen()
        }
        this.ws.onmessage = (data) => {
          if (this.opt.isReconnect && data.data === this.opt.pingString) {
            this.reset().start()
          } else {
            this.onmessage(data)
          }
        }
        this.ws.onclose = () => {
          if (this.opt.isReconnect) this.reconnect()
          this.onclose()
        }
        this.ws.onerror = () => {
          if (this.opt.isReconnect) this.reconnect()
          this.onerror()
        }
      }
      // 设置ws参数
      setWsData() {
        if (this.ws) {
          this.binaryType = this.ws.binaryType
          this.bufferedAmount = this.ws.bufferedAmount
          this.protocol = this.ws.protocol
          this.readyState = this.ws.protocol
        } else {
          this.binaryType = ''
          this.bufferedAmount = null
          this.protocol = ''
          this.readyState = null
        }
      }
      // 发送消息
      send(data) {
        this.ws.send(data)
        return this
      }
      // 关闭连接
      close() {
        this.isClose = true
        this.ws.close()
        return this
      }
      // 清除定时器
      clearTimer() {
        if (this.reconnectTimer) {
          clearTimeout(this.reconnectTimer)
        }
        if (this.timeoutObj) {
          clearTimeout(this.timeoutObj)
        }
        if (this.intervalObj) {
          clearTimeout(this.intervalObj)
        }
      }
      // 开启心跳
      start() {
        this.timeoutObj = setTimeout(() => {
          this.reconnect()
        }, this.opt.timeout)
        return this
      }
      // 重置心跳
      reset() {
        clearTimeout(this.timeoutObj)
        return this
      }
      // 重连
      reconnect() {
        if (this.isClose) {
          this.clearTimer()
          return
        }
        if (this.lockReconnect) return
        this.lockReconnect = true
        if (this.reconnectTimer) clearTimeout(this.reconnectTimer)
        this.reconnectTimer = setTimeout(() => {
          this.createWs()
          this.lockReconnect = false
        }, this.opt.reconnectStep)
        return this
      }
      // ping
      ping() {
        if (this.opt.isReconnect) {
          if (this.intervalObj) clearTimeout(this.intervalObj)
          this.intervalObj = setTimeout(() => {
            if (this.isClose) {
              this.clearTimer()
            } else {
              try {
                if (this.ws) {
                  this.ws.send(this.opt.pingString)
                  this.ping()
                }
              } catch (e) {
                console.info('ws ping error:', e)
              }
            }
          }, this.opt.intervalStep)
        }
      }
    }
  • 相关阅读:
    jxl导出Excel文件
    IOC容器中bean的生命周期
    Hibernate缓存
    Hibernate关联映射及高级查询
    Hibernate简介
    jsp中自定义Taglib案例
    面向对象设计原则
    struts2进阶篇(5)
    Spring核心概念之AOP
    struts2进阶篇(4)
  • 原文地址:https://www.cnblogs.com/lizhiwei8/p/13692393.html
Copyright © 2011-2022 走看看