From 30190a149dfcf465104d08c54ec4e2d4d8074b17 Mon Sep 17 00:00:00 2001
From: wtt <1985833171@qq.com>
Date: 星期一, 19 一月 2026 14:05:38 +0800
Subject: [PATCH] Merge branch 'Dev' of http://101.37.171.70:10101/r/~jhz/STUWMS into Dev

---
 utils/WebSocketServices.js |  252 ++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 193 insertions(+), 59 deletions(-)

diff --git a/utils/WebSocketServices.js b/utils/WebSocketServices.js
index 850b8d8..7115a50 100644
--- a/utils/WebSocketServices.js
+++ b/utils/WebSocketServices.js
@@ -5,82 +5,216 @@
 class WebSocketServices {
     constructor() {
         this.wsInstance = null; // WebSocket 瀹炰緥
-        this.isConnecting = false; // 閬垮厤骞跺彂閲嶈繛
-        this.isConnected = false; // 閬垮厤骞跺彂閲嶈繛
-        this.wsUrl = CommonUtils.httpFormatWs()
+        this.isConnecting = false; // 杩炴帴涓姸鎬侊紙閬垮厤骞跺彂閲嶈繛锛�
+        this.isConnected = false; // 宸茶繛鎺ョ姸鎬�
+        this.isReconnectStopped = false; // 鍋滄閲嶈繛鏍囪
+        this.wsUrl = CommonUtils.httpFormatWs(); // WebSocket 鍩虹鍦板潃
+
+        // 瓒呮椂鏍¢獙閰嶇疆
+        this.businessMessageInterval = 5 * 60 * 1000; 
+        this.noMessageTimeout = this.businessMessageInterval + 2 * 60 * 1000;
+        this.noMessageTimer = null; // 鏃犳秷鎭秴鏃跺畾鏃跺櫒
+
+        // 鐩戝惉鍑芥暟寮曠敤
+        this.openListener = null;
+        this.messageListener = null;
+        this.closeListener = null;
+        this.errorListener = null;
+
+        // 缂撳瓨鐢ㄦ埛淇℃伅
+        this.currentUserId = "";
+        this.currentUserName = "";
     }
 
-    // 寤虹珛WebSocket杩炴帴
-    createConnect(userId, userName) { // 浣跨敤鐢ㄦ埛鏍囪瘑 浣滀负鍚庣杩炴帴鐨勫嚟鎹�
-        console.log('wsUrl: ', this.wsUrl);
-        console.log('userId: ', userId);
-        console.log('userName: ', userName);
-        if (this.isConnecting || !userId || this.isConnected) {
-            return
+    /**
+     * 寤虹珛 WebSocket 杩炴帴
+     * @param {string/number} userId - 鐢ㄦ埛ID锛堝繀濉級
+     * @param {string} userName - 鐢ㄦ埛鍚嶏紙蹇呭~锛�
+     * @param {number} count - 褰撳墠閲嶈繛娆℃暟
+     * @param {number} limit - 鏈�澶ч噸杩炴鏁帮紙榛樿3娆★級
+     */
+    createConnect(userId, userName, count = 0, limit = 3) {
+        // 鐧诲綍寤虹珛杩炴帴鏃讹紝闇�瑕侀噸鏂拌幏鍙杊ttp鍦板潃锛屽彲鑳戒細鍙樻洿
+        this.wsUrl = CommonUtils.httpFormatWs();
+        // 缂撳瓨鐢ㄦ埛淇℃伅锛堢敤浜庨噸杩烇級
+        this.currentUserId = userId;
+        this.currentUserName = userName;
+
+        // 鍓嶇疆鏍¢獙锛氶伩鍏嶆棤鏁堣繛鎺ュ拰骞跺彂閲嶈繛
+        if (this.isConnecting || this.isConnected) return;
+        if (!userId && userId !== 0) { // 鍏煎 userId 涓� 0 鐨勫悎娉曞満鏅�
+            CommonUtils.showTips({
+                message: "鐢ㄦ埛鏍囪瘑涓嶈兘涓虹┖锛屾棤娉曞缓绔媁ebSocket杩炴帴"
+            });
+            return;
         }
+        if (count > limit) {
+            CommonUtils.showTips({
+                message: `WebSocket 閲嶈繛娆℃暟瓒呭嚭鏈�澶ч檺鍒讹紙${limit}娆★級锛屽凡鍋滄閲嶈繛`,
+            });
+            this.isReconnectStopped = true;
+            return;
+        }
+
+        console.log(`[WebSocket] 寮�濮嬪缓绔嬭繛鎺ワ紙绗� ${count || 0} 娆★級`, {
+            wsUrl: this.wsUrl,
+            userId,
+            userName,
+        });
+
+        // 娓呴櫎鍘嗗彶娈嬬暀锛氱洃鍚�+瀹氭椂鍣�
+        this.clearAllListeners();
+        this.clearNoMessageTimer();
+
+        // 鍙戣捣杩炴帴
+        this.isConnecting = true;
         this.wsInstance = uni.connectSocket({
-            url: this.wsUrl + `?userId=${encodeURIComponent(userId)}&userName=${encodeURIComponent(userName)}`,
-            success() {
-                this.isConnecting = true
+            url: `${this.wsUrl}?userId=${encodeURIComponent(userId)}&userName=${encodeURIComponent(userName)}`,
+            fail: (error) => {
+                console.error("[WebSocket] 杩炴帴鍙戣捣澶辫触", error);
+                this.isConnecting = false;
+                this.triggerReconnect(count);
+            },
+        });
+
+        // 鐩戝惉杩炴帴鎴愬姛锛氬惎鍔ㄦ棤娑堟伅瓒呮椂鏍¢獙
+        this.openListener = uni.onSocketOpen((res) => {
+            console.log("[WebSocket] 杩炴帴寤虹珛鎴愬姛", res);
+            this.isConnecting = false;
+            this.isConnected = true;
+            this.isReconnectStopped = false;
+            this.startNoMessageCheck();
+            count = 0;
+        });
+
+        this.messageListener = uni.onSocketMessage((res) => {
+            try {
+                const message = JSON.parse(res.data);
+                console.log("[WebSocket] 鏀跺埌涓氬姟娑堟伅", message);
+
+                // 閲嶇疆鏃犳秷鎭畾鏃跺櫒锛堟湁涓氬姟娑堟伅=杩炴帴姝e父锛�
+                this.resetNoMessageTimer();
+
+                // 澶勭悊涓氬姟娑堟伅
+                if (message.Type === "Message") {
+                    const content = JSON.parse(message.Content);
+                    this.showTaskTip(`鎮ㄦ湁${content.length}鏉℃秷鎭渶瑕佸鐞�!`);
+                    // this.emit("message", content); // 鏀寔澶栭儴鐩戝惉
+                }
+            } catch (error) {
+                console.error("[WebSocket] 娑堟伅瑙f瀽澶辫触", error, res.data);
             }
-        })
+        });
 
-        // 鐩戝惉濂楁帴瀛楄繛鎺ュ缓绔�
-        uni.onSocketOpen((res) => {
-            console.log('[webSocket]: 濂楁帴瀛楄繛鎺ュ缓绔嬫垚鍔�');
-            this.isConnecting = false
-            this.isConnected = true
-            console.log('res: ', res);
-            this.wsInstance = res.socketTask
-        })
+        // 鐩戝惉杩炴帴鍏抽棴锛氫粎寮傚父鍏抽棴瑙﹀彂閲嶈繛
+        this.closeListener = uni.onSocketClose((res) => {
+            console.log("[WebSocket] 杩炴帴鍏抽棴", res);
+            this.isConnecting = false;
+            this.isConnected = false;
+            this.clearNoMessageTimer();
 
-        uni.onSocketMessage((res) => {
-            let message = JSON.parse(res.data)
-            console.log('message: ', message);
-            if (message.Type == 'Message') {
-                // 娑堟伅淇″彿
-                let content = JSON.parse(message.Content)
-                console.log('content: ', content);
-
-                this.showTaskTip(`鎮ㄦ湁${content.length}鏉℃秷鎭渶瑕佸鐞�!`)
-            } else if (message.Type == 'ping') {
-                // 蹇冭烦淇″彿
-                uni.sendSocketMessage({
-                    data: "pong"
-                })
+            // 姝e父鍏抽棴锛坈ode=1000锛夋垨涓诲姩鍋滄閲嶈繛鏃讹紝涓嶉噸杩�
+            if (!this.isReconnectStopped && res.code !== 1000) {
+                this.triggerReconnect(count);
             }
-        })
+        });
+
+        // 鐩戝惉杩炴帴閿欒锛氳Е鍙戦噸杩�
+        this.errorListener = uni.onSocketError((error) => {
+            console.error("[WebSocket] 杩炴帴閿欒", error);
+            this.isConnecting = false;
+            this.clearNoMessageTimer();
+            if (!this.isReconnectStopped) {
+                this.triggerReconnect(count);
+            }
+        });
     }
 
-    // 閲嶈繛
-    reConnect(reCount = 1, limit = 3) {
-        if (reCount > limit) {
-            uni.showToast({
-                icon: 'none',
-                title: `瓒呭嚭鏈�澶ч噸杩炴鏁般�傚凡閫�鍑鸿繛鎺
-            })
-            this.isConnecting = false
-            return
+    /**
+     * 缁熶竴瑙﹀彂閲嶈繛锛堝欢杩�3绉掞級
+     * @param {number} count - 褰撳墠閲嶈繛娆℃暟
+     */
+    triggerReconnect(count) {
+        console.log(`[WebSocket] 鍑嗗绗� ${count + 1} 娆¢噸杩瀈);
+        setTimeout(() => {
+            this.createConnect(this.currentUserId, this.currentUserName, count + 1);
+        }, 3000);
+    }
+
+    /**
+     * 鍚姩鈥滄棤涓氬姟娑堟伅鈥濊秴鏃舵牎楠�
+     */
+    startNoMessageCheck() {
+        this.clearNoMessageTimer();
+        this.noMessageTimer = setTimeout(() => {
+            console.warn("[WebSocket] 7鍒嗛挓鏈敹鍒颁笟鍔℃秷鎭紝鍒ゅ畾杩炴帴澶辨晥锛屼富鍔ㄩ噸杩�");
+            this.closeSocket();
+            this.createConnect(this.currentUserId, this.currentUserName);
+        }, this.noMessageTimeout);
+    }
+
+    /**
+     * 鏀跺埌涓氬姟娑堟伅鍚庯紝閲嶇疆鏃犳秷鎭畾鏃跺櫒
+     */
+    resetNoMessageTimer() {
+        this.startNoMessageCheck();
+    }
+
+    /**
+     * 娓呴櫎鏃犳秷鎭畾鏃跺櫒
+     */
+    clearNoMessageTimer() {
+        if (this.noMessageTimer) {
+            clearTimeout(this.noMessageTimer);
+            this.noMessageTimer = null;
         }
-        uni.showToast({
-            icon: 'none',
-            title: `姝e湪灏濊瘯閲嶈繛锛岄噸杩炴鏁� ${reCount}`
-        })
-
-        reConnect(reCount + 1, limit)
-
-        uni.hideToast()
     }
 
-    // 杩炴帴娉ㄩ攢
-    disConnect() {
-
+    /**
+     * 娓呴櫎鎵�鏈� Socket 鐩戝惉 
+     */
+    clearAllListeners() {
+        if (this.openListener) {
+            uni.offSocketOpen(this.openListener);
+            this.openListener = null;
+        }
+        if (this.messageListener) {
+            uni.offSocketMessage(this.messageListener);
+            this.messageListener = null;
+        }
+        if (this.closeListener) {
+            uni.offSocketClose(this.closeListener);
+            this.closeListener = null;
+        }
+        if (this.errorListener) {
+            uni.offSocketError(this.errorListener);
+            this.errorListener = null;
+        }
     }
+
+    /**
+     * 涓诲姩鍏抽棴 WebSocket 杩炴帴 (鐧诲嚭鏃跺叧闂璚ebSocket杩炴帴)
+     */
+    closeSocket() {
+        this.isReconnectStopped = true;
+        this.clearAllListeners();
+        this.clearNoMessageTimer();
+
+        if (this.wsInstance) {
+            uni.closeSocket({
+                success: () => console.log("[WebSocket] 涓诲姩鍏抽棴杩炴帴鎴愬姛"),
+                fail: (error) => console.error("[WebSocket] 涓诲姩鍏抽棴杩炴帴澶辫触", error),
+            });
+            this.wsInstance = null;
+        }
+
+        this.isConnected = false;
+        this.isConnecting = false;
+    }
+
 
     showTaskTip(Content) {
-        console.log('Content: ', Content);
         // #ifdef APP-PLUS || APP
-        console.log('Content2: ', Content);
         let content = Content;
         let options = {
             title: "閲嶈閫氱煡",

--
Gitblit v1.9.1