Newer
Older
robot_dog_patrol_front / src / store / modules / websocket.ts
dutingting on 24 Feb 4 KB 暂存
import { ElMessage } from 'element-plus'
import useUserStore from './user'

const useWebsocketStore = defineStore('websocket', {
  state: () => ({
    // wsUrl: `ws://${import.meta.env.VITE_APP_API_BASEURL.split('://')[1]}/websocket/${useUserStore().id}`,
    wsUrl: `ws://${
      window.localStorage.getItem('BaseUrl')?.split('http://')[1]
    }/websocket/${useUserStore().id}`,
    websocket: null, // ws连接
    wsStatus: false, // websocket连接状态 true为连接
    wsPingTimer: null, // 心跳定时器
    wsPingTime: 60000, // 心跳定时时长
    wsReconnectCount: 0, // 重连次数
    wsReconnectTimer: null, // 重连定时器
    wsIsReconnect: true, // 是否重连
    data: {} // 接收到的数据
  }),
  getters: {},
  actions: {
    // 连接websocket
    initWebSocket() {
      if (typeof WebSocket === 'undefined') {
        ElMessage({
          message:
            '当前浏览器无法接收实时报警信息,请使用谷歌浏览器、火狐或360浏览器极速模式!',
          type: 'warning'
          // duration: 0,
        })
        this.wsIsReconnect = true
      } else {
        // 实例化socket
        console.log(`**********socketUrl************${this.wsUrl}`)
        this.wsIsReconnect = false
        const socket = new WebSocket(this.wsUrl)
        this.websocket = socket
        // 监听socket打开
        socket.onopen = () => {
          console.log('浏览器WebSocket已打开')
          this.wsStatus = true
          const wsPingTimer = setInterval(() => {
            // 发送心跳
            if (this.wsStatus) {
              try {
                socket.send(
                  JSON.stringify({
                    id: useUserStore().id, // 用户id
                    type: 'heartbeat'
                  })
                )
                console.log(`ping websocket${new Date()}`)
              } catch (err) {
                console.log('心跳发送失败,执行重连', err)
                console.log(`正在尝试重新连接${this.wsReconnectCount}${1}次`)
                // 调用重新链接
                this.reConnectWebsocket()
                this.wsStatus = false
              }
            }
          }, this.wsPingTime)
          this.wsPingTimer = wsPingTimer
        }
        // 监听socket消息接收s
        socket.onmessage = msg => {
          console.log(msg, 'websocket初始')
          // 转换为json对象
          const data = JSON.parse(msg.data)
          this.data = data
          console.log(data, 'websocket 返回消息')
        }
        // 监听socket错误
        socket.onerror = function (err) {
          console.log(err)
          ElMessage({
            message: '无法接收实时报警信息,请检查服务器后重新刷新页面',
            type: 'error'
            // duration: 0,
          })
        }
        // 监听socket关闭
        socket.onclose = () => {
          console.log('WebSocket已关闭')
          this.wsStatus = false
          if (this.wsPingTimer) {
            console.log('停止定时器')
            clearInterval(this.wsPingTimer)
            this.wsPingTimer = null
          }
          if (this.wsReconnectTimer) {
            clearTimeout(this.wsReconnectTimer)
            this.wsReconnectTimer = null
          }
          if (this.wsIsReconnect && this.wsReconnectCount === 0) {
            this.reConnectWebsocket()
          }
        }
      }
    },
    // 断开websocket
    destroyWebSocket() {
      this.wsIsReconnect = false
      if (this.websocket) {
        this.websocket.close()
      }
      if (this.wsPingTimer) {
        console.log('停止定时器')
        clearInterval(this.wsPingTimer)
        this.wsPingTimer = null
      }
      if (this.wsReconnectTimer) {
        clearTimeout(this.wsReconnectTimer)
        this.wsReconnectTimer = null
      }
      this.wsStatus = false
    },
    // websocket重连
    reConnectWebsocket() {
      console.log('重连', this.wsReconnectCount)
      // 逐渐延长重连时间
      var time = 3000
      if (this.wsReconnectCount < 20) {
        time = 3000
      } else if (this.wsReconnectCount < 50) {
        time = 10000
      } else if (this.wsReconnectCount < 100) {
        time = 450000
      } else {
        return false
      }
      const wsReconnectTimer = setTimeout(() => {
        this.initWebSocket()
      }, time)
      this.wsReconnectTimer = wsReconnectTimer
      this.wsReconnectCount = this.wsReconnectCount + 1
    }
  }
})
export default useWebsocketStore