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