Newer
Older
laserPTZFrontV2.0 / src / store / modules / websocket.ts
wangxitong on 26 Sep 8 KB 流媒体
import { ElMessage, ElNotification } from 'element-plus'
import useUserStore from './user'
import { getDictByCode } from '@/api/system/dict'
import { getWsUrl } from '@/utils/auth'
const useWebsocketStore = defineStore(
  'websocket',
  {
    state: () => ({
      // wsUrl: `ws://${config.baseUrl.split('://')[1]}/websocket/${useUserStore().id}`,
      wsUrl: getWsUrl(),
      websocket: null, // ws连接
      wsStatus: false, // websocket连接状态 true为连接
      // wsPingTimer: null, // 心跳定时器
      wsPingTime: 60000, // 心跳定时时长
      wsReconnectCount: 0, // 重连次数
      wsReconnectTimer: null, // 重连定时器
      wsIsReconnect: true, // 是否重连
      wsData: {}, // 默认提醒
      wsImgData: {}, // 图片报警提醒
      lineData: {}, // 折线图添加数据
      videoData: {}, // 视频数据返回
      codeList: {},
      refreshMap: false,
    }),
    getters: {},
    actions: {
      // 连接websocket
      initWebSocket(router) {
        if (typeof (WebSocket) === 'undefined') {
          ElMessage({
            message: '当前浏览器无法接收实时报警信息,请使用谷歌浏览器、火狐或360浏览器极速模式!',
            type: 'warning',
            // duration: 0,
          })
          this.wsIsReconnect = true
        }
        else {
          // 实例化socket
          console.log('**********socketUrl************', getWsUrl() + useUserStore().id)
          this.wsIsReconnect = false
          const socket = new WebSocket(getWsUrl() + useUserStore().id)
          this.websocket = socket
          // 监听socket打开
          socket.onopen = () => {
            console.log('浏览器WebSocket已打开')
            getDictByCode('alarmType').then((res) => {
              res.data.map((item) => {
                this.codeList[item.value] = item.name
              })
            })
            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消息接收
          socket.onmessage = (msg) => {
            // 转换为json对象
            const data = JSON.parse(msg.data)
            // console.log(data, 'websocket 返回消息')
            this.wsData = {}
            this.wsImgData = {}
            this.lineData = {}
            this.refreshMap = false
            const observerData = data
            const type = observerData.type
            // 存在报警图片的时候展示图片
            this.wsData = observerData
            let str = ''
            let msgTypeName = ''
            let id = ''
            // 甲烷浓度更新
            if (type == 'gasAlarm') {
              this.videoData = {
                deviceIp: observerData.deviceIp,
                concentration: observerData.concentration,
                horizontalAngle: observerData.alarmDirection,
                verticalAngle: observerData.alarmPitch,
                deviceStatusName: '报警',
              }
              msgTypeName = '甲烷浓度告警'
              id = observerData.monitorId
              str = `${observerData.monitorName}: ${observerData.concentration}ppm·m(${observerData.alarmDirection}°,${observerData.alarmPitch}°)`
              this.refreshMap = true
            }
            else if (type == 'presetIndex') { // 预置点更新
              this.videoData = {
                deviceIp: observerData.deviceIp,
                stationName: observerData.name,
              }
              // 图片报警
            }
            else if (type == 'AIAlarm') {
              this.wsImgData = observerData
              this.videoData = {
                deviceIp: observerData.deviceIp,
                deviceStatusName: '报警',
              }
              this.refreshMap = true
            }
            else if (type == 'onLine') {
              this.videoData = {
                deviceIp: observerData.deviceIp,
                deviceStatusName: '在线',
              }
              this.refreshMap = true
            }
            else if (type == 'offLine') {
              this.videoData = {
                deviceIp: observerData.deviceIp,
                deviceStatusName: '离线',
              }
              this.refreshMap = true
            }
            else {
              // console.log('其他状态', data)
              this.videoData = {
                deviceIp: observerData.deviceIp,
                concentration: observerData.gasData,
                horizontalAngle: observerData.horizontal,
                verticalAngle: observerData.verticalAngle,
                // deviceStatusName:'报警'
              }
              this.lineData = {
                deviceIp: observerData.deviceIp, // 获取返回deviceIp
                gasData: observerData.gasData,
                time: observerData.time,
              }
            }
            if (Object.values(this.wsData).length >= 2 && msgTypeName !== '') {
              ElNotification({
                dangerouslyUseHTMLString: true,
                title: msgTypeName,
                message: str,
                type: 'warning',
                position: 'top-left',
                offset: 460,
                onClick: () => {
                  router.push({
                    path: '/home/control',
                    query: {
                      id,
                    },
                  })
                },
              })
            }
          }
          // 监听socket错误
          socket.onerror = function () {
            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