websocket+心跳

1.直接上代码

let ws //websocket实例
let lockReconnect = false //避免重复连接
let wsUrl = ''
//初始化websocket
getWebSocketurl()
async function getWebSocketurl() {
  try {
    // const data = await getInfo()
    sid.value = localStorage.getItem('Refresh-Token')
    wsUrl = `ws://192.168.2.158/webSocket/${sid.value}`
    createWebSocket(wsUrl)
  } catch (e) {
    console.log(e)
  }
}
//前面都是准备工作
async function createWebSocket(url) {
  try {
    ws = new WebSocket(wsUrl) //创建websocket链接
    initEventHandle() //后续操作
  } catch (e) {
    reconnect(url)
  }
}

function initEventHandle() {
  ws.onclose = function (evnt) {
    console.log('websocket服务关闭了')
    reconnect(wsUrl)  
  }
  ws.onerror = function (evnt) {
    console.log('websocket服务出错了')
    reconnect(wsUrl)
  }
  ws.onopen = function (evnt) {
    console.log('websocket服务开始')
    sendMsg.value = JSON.stringify(sendMsg.value)
    ws.send(sendMsg.value)
    //心跳检测重置
    heartCheck.reset().start()
  }
  ws.onmessage = function (evnt) {
    //如果获取到消息,心跳检测重置
    //拿到任何消息都说明当前连接是正常的
    console.log('websocket服务获得数据了')
    //接受消息后的UI变化
    doWithMsg(evnt.data) //收到消息进行页面操作
     //心跳检测重置
    heartCheck.reset().start()
  }

  //收到消息推送
  function doWithMsg(msg) {
        //  收到消息操作页面、、  
  }
  
function reconnect(url) {
  if (lockReconnect) return
  lockReconnect = true
  //没连接上会一直重连,设置延迟避免请求过多
  setTimeout(function () {
    createWebSocket(url)
    lockReconnect = false
  }, 2000)
}

//心跳检测
let heartCheck = {
  timeout: 600000, //60秒
  timeoutObj: null,
  serverTimeoutObj: null,
  reset: function () {
    clearTimeout(this.timeoutObj)
    clearTimeout(this.serverTimeoutObj)
    return this
  },
  start: function () {
    let self = this
    this.timeoutObj = setTimeout(function () {
      //这里发送一个心跳,后端收到后,返回一个心跳消息,
      //onmessage拿到返回的心跳就说明连接正常
      // ws.send('HeartBeat')
      ws.send(sendMsg.value)
      self.serverTimeoutObj = setTimeout(function () {
        //如果超过一定时间还没重置,说明后端主动断开了
        ws.close() //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
      }, self.timeout)
    }, this.timeout)
  },
}

2.另一种

<template>

</template>
<script>
import store from '@/store'

export default {
  props: {
    uri: {
      type: String
    },
  },
  data() {
    return {
      webSocket: null, // webSocket实例
      lockReconnect: false, // 重连锁,避免多次重连
      maxReconnect: 6,  // 最大重连次数, -1 标识无限重连
      reconnectTime: 0, // 重连尝试次数
      heartbeat: {
        interval: 30 * 1000, // 心跳间隔时间
        timeout: 10 * 1000, // 响应超时时间
        pingTimeoutObj: null, // 延时发送心跳的定时器
        pongTimeoutObj: null, // 接收心跳响应的定时器
        pingMessage: JSON.stringify({type: 'ping'}) // 心跳请求信息
      }
    }
  },
  computed: {
    token() {
      return store.getters.access_token
    },
    tenant() {
      return store.getters.userInfo.tenantId ? store.getters.userInfo.tenantId : 1;
    }
  },
  created() {
    this.initWebSocket()
  },
  destroyed: function () {
    this.webSocket.close()
    this.clearTimeoutObj(this.heartbeat)
  },
  methods: {
    /**
     * 初始化 weoSocket
     */
    initWebSocket() {
      // ws地址
      let host = window.location.host;
      let wsUri = `ws://${host}${this.uri}?access_token=${this.token}&TENANT-ID=${this.tenant}`
      // 建立连接
      this.webSocket = new WebSocket(wsUri)
      // 连接成功
      this.webSocket.onopen = this.onOpen
      // 连接错误
      this.webSocket.onerror = this.onError
      // 接收信息
      this.webSocket.onmessage = this.onMessage
      // 连接关闭
      this.webSocket.onclose = this.onClose
    },
    /**
     * 重新连接
     */
    reconnect() {
      if (!this.token) {
        return
      }
      if (this.lockReconnect || (this.maxReconnect !== -1 && this.reconnectTime > this.maxReconnect)) {
        return
      }
      this.lockReconnect = true
      setTimeout(() => {
        this.reconnectTime++
        // 建立新连接
        this.initWebSocket()
        this.lockReconnect = false
      }, 5000)
    },
    /**
     * 清空定时器
     */
    clearTimeoutObj: function (heartbeat) {
      heartbeat.pingTimeoutObj && clearTimeout(heartbeat.pingTimeoutObj)
      heartbeat.pongTimeoutObj && clearTimeout(heartbeat.pongTimeoutObj)
    },
    /**
     * 开启心跳
     */
    startHeartbeat() {
      const webSocket = this.webSocket
      const heartbeat = this.heartbeat
      // 清空定时器
      this.clearTimeoutObj(heartbeat)
      // 延时发送下一次心跳
      heartbeat.pingTimeoutObj = setTimeout(() => {
        // 如果连接正常
        if (webSocket.readyState === 1) {
          //这里发送一个心跳,后端收到后,返回一个心跳消息,
          webSocket.send(heartbeat.pingMessage)
          // 心跳发送后,如果服务器超时未响应则断开,如果响应了会被重置心跳定时器
          heartbeat.pongTimeoutObj = setTimeout(() => {
            webSocket.close()
          }, heartbeat.timeout)
        } else {
          // 否则重连
          this.reconnect()
        }
      }, heartbeat.interval)
    },
    /**
     * 连接成功事件
     */
    onOpen() {
      console.log('WebSocket connection success')
      //开启心跳
      this.startHeartbeat()
      this.reconnectTime = 0
    },
    /**
     * 连接失败事件
     * @param e
     */
    onError(e) {
      //错误
      console.log(`WebSocket connection error:${e.code} ${e.reason} ${e.wasClean}`)
      //重连
      this.reconnect()
    },
    /**
     * 连接关闭事件
     * @param e
     */
    onClose(e) {
      //关闭
      console.log(`WebSocket connection closed:${e.code} ${e.reason} ${e.wasClean}`)
      //重连
      this.reconnect()
    },
    /**
     * 接收服务器推送的信息
     * @param msgEvent
     */
    onMessage(msgEvent) {
      //收到服务器信息,心跳重置并发送
      this.startHeartbeat()
      const text = msgEvent.data

      if (text.indexOf('pong') > 0) {
        return
      }

      this.$notify.warning({
        title: '消息提醒',
        dangerouslyUseHTMLString: true,
        message: text + '请及时处理',
        offset: 60
      })
    },
    /**
     * 数据发送
     * @param msg
     */
    send(msg) {
      //数据发送
      this.webSocket.send(msg)
    }
  }
}

</script>

相关推荐

  1. websocket+心跳

    2024-03-10 23:50:04       47 阅读
  2. Golang WebSocket 心跳

    2024-03-10 23:50:04       58 阅读
  3. springboot webscoket示例:增加定时心跳逻辑

    2024-03-10 23:50:04       40 阅读
  4. uniapp封装websocket以及心跳检测、重连

    2024-03-10 23:50:04       35 阅读
  5. vue封装websocket以及心跳检测、重连

    2024-03-10 23:50:04       35 阅读
  6. WebSocket 断网重连、心跳检测功能封装

    2024-03-10 23:50:04       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-10 23:50:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-10 23:50:04       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-10 23:50:04       82 阅读
  4. Python语言-面向对象

    2024-03-10 23:50:04       91 阅读

热门阅读

  1. uniapp 开发app,如何使用模拟器

    2024-03-10 23:50:04       40 阅读
  2. linux系统安装docker

    2024-03-10 23:50:04       33 阅读
  3. CatBoost高级教程:分布式训练与大规模数据处理

    2024-03-10 23:50:04       38 阅读
  4. Linux运维_Bash脚本_编译安装Mesa-23.3.6(OpenGL)

    2024-03-10 23:50:04       32 阅读
  5. 从零开始 TensorRT(7)C++ 篇:解析 ONNX

    2024-03-10 23:50:04       44 阅读
  6. 云贝福利课程倒计时-Oracle小课

    2024-03-10 23:50:04       32 阅读
  7. 202109CSPT4收集卡牌

    2024-03-10 23:50:04       34 阅读
  8. TypeScript的基础类型和高级类型梳理总结

    2024-03-10 23:50:04       41 阅读
  9. 安装pytorch省流版

    2024-03-10 23:50:04       39 阅读