ZaiZai 7 months ago
parent
commit
036f8a31c1
2 changed files with 63 additions and 39 deletions
  1. 4 2
      src/layout/index.vue
  2. 59 37
      src/plugins/HcSocket.js

+ 4 - 2
src/layout/index.vue

@@ -51,7 +51,7 @@ import { getToken } from '~src/api/auth'
 import { useRoute, useRouter } from 'vue-router'
 import { initButtons } from '~sto/app'
 import { isNullES } from 'js-fast-way'
-import HcSocket from '~src/plugins/HcSocket'
+import { HcSocket } from '~src/plugins/HcSocket'
 import messageApi from '~api/tasks/message'
 
 //初始组合式
@@ -124,6 +124,7 @@ const menuBarChange = ({ code }) => {
 }
 
 //项目合同段的ID
+let socket
 const timeExamples = ref()
 const times = ref(10000)
 const cascaderSend = async ({ projectId, contractId }) => {
@@ -133,7 +134,8 @@ const cascaderSend = async ({ projectId, contractId }) => {
         return
     }
     //链接webSocket
-    HcSocket.create({ projectId, contractId, userId: userId.value }, (data) => {
+    if (!isNullES(socket)) socket.close()
+    socket = new HcSocket({ projectId, contractId, userId: userId.value }, (data) => {
         console.log('socket:', data)
     })
     //先获取一次

+ 59 - 37
src/plugins/HcSocket.js

@@ -1,58 +1,80 @@
 import website from '~src/config/index'
-import { isNullES } from 'js-fast-way'
+import { getObjValue, isNullES } from 'js-fast-way'
 
 // 长链接推送插件
-export default class HcSocket {
+class HcSocket {
 
-    static socket = null
+    limit = 30
+    interval = 1000
 
-    static create({ projectId, contractId, userId }, change) {
-        const url = `${website.socket}/${website.clientId}/${projectId}/${contractId}/${userId}`
-        const socket = new WebSocket(url)
-        socket.onopen = function () {
-            console.log('websocket 链接成功')
+    constructor(data, change) {
+        this.param = getObjValue(data)
+        this.onChange = change
+        this.socket = null
+        this.create()
+    }
+
+    //创建连接
+    create() {
+        const { projectId, contractId, userId } = this.param
+        const { socket: socketUrl, clientId } = website
+        if (isNullES(socketUrl) || isNullES(clientId) || isNullES(projectId) || isNullES(contractId) || isNullES(userId)) {
+            return
+        }
+        //拼接URL并登录socket
+        const url = `${socketUrl}/${clientId}/${projectId}/${contractId}/${userId}`
+        this.socket = new WebSocket(url)
+        this.socket.onopen = function () {
+            console.log('WebSocket 链接成功')
         }
-        socket.onclose = function () {
-            console.log('websocket 链接已断开')
+        this.socket.onclose = function () {
+            console.log('WebSocket 链接已断开')
+            this.reconnect()
         }
-        socket.onmessage = function ({ data }) {
+        this.socket.onmessage = function ({ data }) {
             console.log(data)
-            if (typeof change !== 'function') {
-                return false
-            } else {
-                change(JSON.parse(data))
+            try {
+                const parsedData = JSON.parse(data)
+                if (typeof this.onChange === 'function') {
+                    this.onChange(parsedData)
+                }
+            } catch (error) {
+                console.error('解析 WebSocket 数据时出错:', error)
             }
         }
-        socket.onerror = function ({ data }) {
-            console.log('websocket 发生错误:', data)
+        this.socket.onerror = function ({ data }) {
+            console.log('WebSocket 发生错误:', data)
         }
-        this.socket = socket
     }
 
     //发送消息
-    static async send(data) {
-        const is_socket = await this.isSocket()
-        if (!is_socket) return false
+    async send(data) {
+        if (!this.isSocket()) return
         this.socket.send(data)
     }
 
     //链接是否存在
-    static async isSocket(i = 0) {
-        let _this = this
-        return new Promise((resolve) => {
-            if (isNullES(_this.socket)) {
-                if (i <= 30) {
-                    setTimeout(async () => {
-                        i++
-                        resolve(await _this.isSocket(i))
-                    }, 1000)
-                } else {
-                    resolve(false)
-                }
-            } else {
-                resolve(true)
-            }
-        })
+    isSocket() {
+        return !isNullES(this.socket) && (this.socket.readyState === WebSocket.OPEN)
     }
 
+    //尝试重连
+    async reconnect(attempts = 0) {
+        if (attempts >= this.limit) return
+        if (isNullES(this.socket) || this.socket.readyState === WebSocket.CLOSED) {
+            this.create()
+        }
+        await new Promise(resolve => setTimeout(resolve, this.interval))
+        if (!this.isSocket()) {
+            this.reconnect(attempts + 1)
+        }
+    }
+
+    //关闭或断开连接
+    close() {
+        if (!this.isSocket()) return
+        this.socket.close()
+    }
 }
+
+export { HcSocket }