Quellcode durchsuchen

feat: 添加websocket支持,完成任务后,自动刷新页面

WANGKANG vor 5 Monaten
Ursprung
Commit
663c8f4f90

+ 4 - 0
.env.development

@@ -30,3 +30,7 @@ VITE_PROXY = [["/api","http://localhost:9090"]]
 # VITE_PROXY = [["/api","https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e"]]
 # VITE_PROXY = [["/api","https://www.fastmock.site/mock/f81e8333c1a9276214bcdbc170d9e0a0"]]
 # VITE_PROXY = [["/api-easymock","https://mock.mengxuegu.com"],["/api-fastmock","https://www.fastmock.site"]]
+
+# websocket 开关
+VITE_APP_WEBSOCKET = true
+VITE_WEBSOCKET_URL = "localhost:9090/resource/websocket"

+ 15 - 0
src/stores/modules/websocket.ts

@@ -0,0 +1,15 @@
+import { defineStore } from 'pinia'
+import { Ref, ref } from 'vue'
+
+import { initWebSocket } from '@/utils/websocket'
+
+const useWebSocketStore = defineStore('WebSocket', () => {
+  let protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'
+  const websocket: Ref<WebSocket> = ref(initWebSocket(protocol + import.meta.env.VITE_WEBSOCKET_URL))
+
+  return {
+    websocket
+  }
+})
+
+export default useWebSocketStore

+ 139 - 0
src/utils/websocket.ts

@@ -0,0 +1,139 @@
+/**
+ * @module initWebSocket 初始化
+ * @module websocketonopen 连接成功
+ * @module websocketonerror 连接失败
+ * @module websocketclose 断开连接
+ * @module resetHeart 重置心跳
+ * @module sendSocketHeart 心跳发送
+ * @module reconnect 重连
+ * @module sendMsg 发送数据
+ * @module websocketonmessage 接收数据
+ * @module test 测试收到消息传递
+ * @description socket 通信
+ * @param {any} url socket地址
+ * @param {any} websocket websocket 实例
+ * @param {any} heartTime 心跳定时器实例
+ * @param {number} socketHeart 心跳次数
+ * @param {number} HeartTimeOut 心跳超时时间
+ * @param {number} socketError 错误次数
+ */
+
+import { getToken } from '@/utils/token'
+// import { ElNotification } from 'element-plus'
+// import useNoticeStore from '@/store/modules/notice'
+
+let socketUrl: any = '' // socket地址
+let websocket: any = null // websocket 实例
+let heartTime: any = null // 心跳定时器实例
+let socketHeart = 0 as number // 心跳次数
+const HeartTimeOut = 10000 // 心跳超时时间 10000 = 10s
+let socketError = 0 as number // 错误次数
+
+// 初始化socket
+export const initWebSocket = (url: any) => {
+  if (import.meta.env.VITE_APP_WEBSOCKET === 'false') {
+    return
+  }
+  socketUrl = url
+  // 初始化 websocket
+  websocket = new WebSocket(url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID)
+  websocketonopen()
+  websocketonmessage()
+  websocketonerror()
+  websocketclose()
+  sendSocketHeart()
+  return websocket
+}
+
+// socket 连接成功
+export const websocketonopen = () => {
+  websocket.onopen = function () {
+    console.log('连接 websocket 成功')
+    resetHeart()
+  }
+}
+
+// socket 连接失败
+export const websocketonerror = () => {
+  websocket.onerror = function (e: any) {
+    console.log('连接 websocket 失败', e)
+  }
+}
+
+// socket 断开链接
+export const websocketclose = () => {
+  websocket.onclose = function (e: any) {
+    console.log('断开连接', e)
+  }
+}
+
+// socket 重置心跳
+export const resetHeart = () => {
+  socketHeart = 0
+  socketError = 0
+  clearInterval(heartTime)
+  sendSocketHeart()
+}
+
+// socket心跳发送
+export const sendSocketHeart = () => {
+  heartTime = setInterval(() => {
+    // 如果连接正常则发送心跳
+    if (websocket.readyState == 1) {
+      // if (socketHeart <= 30) {
+      websocket.send(
+        JSON.stringify({
+          type: 'ping'
+        })
+      )
+      socketHeart = socketHeart + 1
+    } else {
+      // 重连
+      reconnect()
+    }
+  }, HeartTimeOut)
+}
+
+// socket重连
+export const reconnect = () => {
+  if (socketError <= 2) {
+    clearInterval(heartTime)
+    initWebSocket(socketUrl)
+    socketError = socketError + 1
+    // eslint-disable-next-line prettier/prettier
+    //console.log('socket重连', socketError);
+  } else {
+    // eslint-disable-next-line prettier/prettier
+    //console.log('重试次数已用完');
+    clearInterval(heartTime)
+  }
+}
+
+// socket 发送数据
+export const sendMsg = (data: any) => {
+  websocket.send(data)
+}
+
+// socket 接收数据
+export const websocketonmessage = () => {
+  websocket.onmessage = function (e: any) {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart()
+    }
+    if (e.data.indexOf('ping') > 0) {
+      return
+    }
+    // useNoticeStore().addNotice({
+    //   message: e.data,
+    //   read: false,
+    //   time: new Date().toLocaleString()
+    // });
+    // ElNotification({
+    //   title: '消息',
+    //   message: e.data,
+    //   type: 'success',
+    //   duration: 3000
+    // });
+    return e.data
+  }
+}

+ 15 - 29
src/views/demo/TargetDetection/index.vue

@@ -167,36 +167,22 @@ import ViewLog from '@/views/demo/components/ViewLog.vue'
 import { AlgorithmType2 } from '@/views/demo/utils'
 import { addAlgorithmModelTrackApi } from '@/api/modules/demo/AlgorithmModelTrack'
 
-import { Status } from '@/views/demo/utils'
-
-const timerRefreshTable = ref()
-const clearTimerRefreshTable = () => {
-  if (timerRefreshTable.value) {
-    clearInterval(timerRefreshTable.value)
-  }
-}
-const refreshTable = () => {
-  clearTimerRefreshTable()
-  timerRefreshTable.value = setInterval(async () => {
-    await proTable.value?.getTableList(false)
-    console.log('refresh table')
-    const tableData = proTable.value?.tableData
-    let flag = false
-    if (tableData) {
-      console.log(tableData)
-      for (const item of tableData) {
-        if (item.status === Status['运行中']) {
-          flag = true
-          break
-        }
-      }
+import useWebSocketStore from '@/stores/modules/websocket'
+import { resetHeart } from '@/utils/websocket'
+
+onMounted(() => {
+  const websocketStore = useWebSocketStore()
+  websocketStore.websocket.onmessage = (e: any) => {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart()
     }
-    if (!flag) {
-      clearTimerRefreshTable()
+    if (e.data.indexOf('ping') > 0) {
+      return
     }
-  }, 5000)
-}
-
+    // console.log(e)
+    proTable.value?.getTableList(true)
+  }
+})
 const enumsAlgorithmConfigTrack = ref<any>([])
 onMounted(async () => {
   const result = await enumAlgorithmConfigTrackApi()
@@ -317,7 +303,7 @@ const startTargetDetection = async (params: any) => {
   } else {
     ElMessage.error('任务开始失败,请检查!')
   }
-  refreshTable()
+  proTable.value?.getTableList()
 }
 
 const openModelDialog = async row => {

+ 14 - 27
src/views/demo/toInfrared/index.vue

@@ -170,35 +170,22 @@ import PreviewCompareImages from '@/views/demo/components/PreviewCompareImages.v
 import { addAlgorithmModelTrackApi } from '@/api/modules/demo/AlgorithmModelTrack'
 import ViewLog from '@/views/demo/components/ViewLog.vue'
 
-import { Status } from '@/views/demo/utils'
+import useWebSocketStore from '@/stores/modules/websocket'
+import { resetHeart } from '@/utils/websocket'
 
-const timerRefreshTable = ref()
-const clearTimerRefreshTable = () => {
-  if (timerRefreshTable.value) {
-    clearInterval(timerRefreshTable.value)
-  }
-}
-const refreshTable = () => {
-  clearTimerRefreshTable()
-  timerRefreshTable.value = setInterval(async () => {
-    await proTable.value?.getTableList(false)
-    console.log('refresh table')
-    const tableData = proTable.value?.tableData
-    let flag = false
-    if (tableData) {
-      console.log(tableData)
-      for (const item of tableData) {
-        if (item.status === Status['运行中']) {
-          flag = true
-          break
-        }
-      }
+onMounted(() => {
+  const websocketStore = useWebSocketStore()
+  websocketStore.websocket.onmessage = (e: any) => {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart()
     }
-    if (!flag) {
-      clearTimerRefreshTable()
+    if (e.data.indexOf('ping') > 0) {
+      return
     }
-  }, 2500)
-}
+    // console.log(e)
+    proTable.value?.getTableList(true)
+  }
+})
 
 const previewImagesRef = ref()
 const dialogVisible = ref(false)
@@ -355,7 +342,7 @@ const startToInfrared = async (params: any) => {
   } else {
     ElMessage.error('任务开始失败,请检查!')
   }
-  refreshTable()
+  proTable.value?.getTableList()
 }
 
 const stopToInfrared = async (params: any) => {

+ 15 - 29
src/views/demo/trackSequence/index.vue

@@ -168,36 +168,22 @@ import statusEnums from '@/utils/status'
 import { AlgorithmType, SubSystem, SubSystem__, enumsAlgorithmType, enumsSubSystem, AlgorithmType2 } from '@/views/demo/utils'
 import ViewLog from '@/views/demo/components/ViewLog.vue'
 import { addAlgorithmModelTrackApi } from '@/api/modules/demo/AlgorithmModelTrack'
-
-import { Status } from '@/views/demo/utils'
-
-const timerRefreshTable = ref()
-const clearTimerRefreshTable = () => {
-  if (timerRefreshTable.value) {
-    clearInterval(timerRefreshTable.value)
-  }
-}
-const refreshTable = () => {
-  clearTimerRefreshTable()
-  timerRefreshTable.value = setInterval(async () => {
-    await proTable.value?.getTableList(false)
-    console.log('refresh table')
-    const tableData = proTable.value?.tableData
-    let flag = false
-    if (tableData) {
-      console.log(tableData)
-      for (const item of tableData) {
-        if (item.status === Status['运行中']) {
-          flag = true
-          break
-        }
-      }
+import useWebSocketStore from '@/stores/modules/websocket'
+import { resetHeart } from '@/utils/websocket'
+
+onMounted(() => {
+  const websocketStore = useWebSocketStore()
+  websocketStore.websocket.onmessage = (e: any) => {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart()
     }
-    if (!flag) {
-      clearTimerRefreshTable()
+    if (e.data.indexOf('ping') > 0) {
+      return
     }
-  }, 7000)
-}
+    // console.log(e)
+    proTable.value?.getTableList(true)
+  }
+})
 
 const enumsAlgorithmConfigTrack_addModel____ = ref<any>([])
 
@@ -466,7 +452,7 @@ const startTrackSequence = async (params: any) => {
   } else {
     ElMessage.error('任务开始失败,请检查!')
   }
-  refreshTable()
+  proTable.value?.getTableList()
 }
 
 const stopTrackSequence = async (params: any) => {

+ 18 - 1
src/views/demo/videoStable/index.vue

@@ -79,7 +79,7 @@
 </template>
 
 <script setup lang="tsx" name="VideoStable">
-import { ref, reactive } from 'vue'
+import { ref, reactive, onMounted } from 'vue'
 import { useHandleData } from '@/hooks/useHandleData'
 import { useDownload } from '@/hooks/useDownload'
 import { ElMessageBox, ElMessage } from 'element-plus'
@@ -103,6 +103,23 @@ import {
   getImagesApi
 } from '@/api/modules/demo/videoStable'
 
+import useWebSocketStore from '@/stores/modules/websocket'
+import { resetHeart } from '@/utils/websocket'
+
+onMounted(() => {
+  const websocketStore = useWebSocketStore()
+  websocketStore.websocket.onmessage = (e: any) => {
+    if (e.data.indexOf('heartbeat') > 0) {
+      resetHeart()
+    }
+    if (e.data.indexOf('ping') > 0) {
+      return
+    }
+    // console.log(e)
+    proTable.value?.getTableList(true)
+  }
+})
+
 const dialogVisible = ref(false)
 const imageIdx = ref(0)
 const imageUrlList: any = ref([])