Просмотр исходного кода

Enhance WebSocket client connection logic and improve event listener management (#3636)

- Updated WebSocketClient to allow connection during CONNECTING state.
- Introduced a flag for reconnection attempts.
- Improved event listener registration to prevent duplicate callbacks.
- Refactored online clients update logic in inbounds.html for better performance and clarity.
- Added CSS styles for subscription link boxes in subpage.html to enhance UI consistency and interactivity.

Co-authored-by: lolka1333 <[email protected]>
lolka1333 1 день назад
Родитель
Сommit
77fa976ee9
3 измененных файлов с 70 добавлено и 27 удалено
  1. 7 2
      web/assets/js/websocket.js
  2. 24 8
      web/html/inbounds.html
  3. 39 17
      web/html/settings/panel/subscription/subpage.html

+ 7 - 2
web/assets/js/websocket.js

@@ -14,10 +14,12 @@ class WebSocketClient {
   }
   }
 
 
   connect() {
   connect() {
-    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+    if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
       return;
       return;
     }
     }
 
 
+    this.shouldReconnect = true;
+
     const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
     const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
     // Ensure basePath ends with '/' for proper URL construction
     // Ensure basePath ends with '/' for proper URL construction
     let basePath = this.basePath || '';
     let basePath = this.basePath || '';
@@ -97,7 +99,10 @@ class WebSocketClient {
     if (!this.listeners.has(event)) {
     if (!this.listeners.has(event)) {
       this.listeners.set(event, []);
       this.listeners.set(event, []);
     }
     }
-    this.listeners.get(event).push(callback);
+    const callbacks = this.listeners.get(event);
+    if (!callbacks.includes(callback)) {
+      callbacks.push(callback);
+    }
   }
   }
 
 
   off(event, callback) {
   off(event, callback) {

+ 24 - 8
web/html/inbounds.html

@@ -1602,7 +1602,6 @@
           if (payload && Array.isArray(payload)) {
           if (payload && Array.isArray(payload)) {
             // Use setInbounds to properly convert to DBInbound objects with methods
             // Use setInbounds to properly convert to DBInbound objects with methods
             this.setInbounds(payload);
             this.setInbounds(payload);
-            this.searchInbounds(this.searchKey);
           }
           }
         });
         });
 
 
@@ -1614,14 +1613,31 @@
           
           
           // Update online clients list in real-time
           // Update online clients list in real-time
           if (payload && Array.isArray(payload.onlineClients)) {
           if (payload && Array.isArray(payload.onlineClients)) {
-            this.onlineClients = payload.onlineClients;
-            // Recalculate client counts to update online status
-            this.dbInbounds.forEach(dbInbound => {
-              const inbound = this.inbounds.find(ib => ib.id === dbInbound.id);
-              if (inbound && this.clientCount[dbInbound.id]) {
-                this.clientCount[dbInbound.id] = this.getClientCounts(dbInbound, inbound);
+            const nextOnlineClients = payload.onlineClients;
+            let onlineChanged = this.onlineClients.length !== nextOnlineClients.length;
+            if (!onlineChanged) {
+              const prevSet = new Set(this.onlineClients);
+              for (const email of nextOnlineClients) {
+                if (!prevSet.has(email)) {
+                  onlineChanged = true;
+                  break;
+                }
               }
               }
-            });
+            }
+            this.onlineClients = nextOnlineClients;
+            if (onlineChanged) {
+              // Recalculate client counts to update online status
+              this.dbInbounds.forEach(dbInbound => {
+                const inbound = this.inbounds.find(ib => ib.id === dbInbound.id);
+                if (inbound && this.clientCount[dbInbound.id]) {
+                  this.clientCount[dbInbound.id] = this.getClientCounts(dbInbound, inbound);
+                }
+              });
+
+              if (this.enableFilter) {
+                this.filterInbounds();
+              }
+            }
           }
           }
           
           
           // Update last online map in real-time
           // Update last online map in real-time

+ 39 - 17
web/html/settings/panel/subscription/subpage.html

@@ -5,6 +5,43 @@
 <script src="{{ .base_path }}assets/ant-design-vue/antd.min.js"></script>
 <script src="{{ .base_path }}assets/ant-design-vue/antd.min.js"></script>
 <script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
 <script src="{{ .base_path }}assets/js/util/index.js?{{ .cur_ver }}"></script>
 <script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
 <script src="{{ .base_path }}assets/qrcode/qrious2.min.js?{{ .cur_ver }}"></script>
+<style>
+    .subscription-page .subscription-link-box {
+        cursor: pointer;
+        border-radius: 12px;
+        padding: 25px 20px 15px 20px;
+        margin-top: -12px;
+        word-break: break-all;
+        font-size: 13px;
+        line-height: 1.5;
+        text-align: left;
+        font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
+        transition: all 0.3s;
+        box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+    }
+
+    .dark.subscription-page .subscription-link-box {
+        background: rgba(0, 0, 0, 0.2);
+        border: 1px solid rgba(255, 255, 255, 0.1);
+        color: #fff;
+    }
+
+    .dark.subscription-page .subscription-link-box:hover {
+        background: rgba(0, 0, 0, 0.3);
+        border-color: rgba(255, 255, 255, 0.2);
+    }
+
+    .light.subscription-page .subscription-link-box {
+        background: rgba(0, 0, 0, 0.03);
+        border: 1px solid rgba(0, 0, 0, 0.08);
+        color: rgba(0, 0, 0, 0.85);
+    }
+
+    .light.subscription-page .subscription-link-box:hover {
+        background: rgba(0, 0, 0, 0.05);
+        border-color: rgba(0, 0, 0, 0.14);
+    }
+</style>
 {{ template "page/head_end" .}}
 {{ template "page/head_end" .}}
 
 
 {{ template "page/body_start" .}}
 {{ template "page/body_start" .}}
@@ -138,27 +175,12 @@
                                 style="margin-bottom: -10px; position: relative; z-index: 2; box-shadow: 0 2px 4px rgba(0,0,0,0.2);">
                                 style="margin-bottom: -10px; position: relative; z-index: 2; box-shadow: 0 2px 4px rgba(0,0,0,0.2);">
                                 <span>[[ linkName(link, idx) ]]</span>
                                 <span>[[ linkName(link, idx) ]]</span>
                             </a-tag>
                             </a-tag>
-                            <div @click="copy(link)" style="
-                                cursor: pointer;
-                                background: rgba(0, 0, 0, 0.2);
-                                border: 1px solid rgba(255, 255, 255, 0.1);
-                                border-radius: 12px;
-                                padding: 25px 20px 15px 20px;
-                                margin-top: -12px;
-                                word-break: break-all;
-                                color: #fff;
-                                font-size: 13px;
-                                line-height: 1.5;
-                                text-align: left;
-                                font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
-                                transition: all 0.3s;
-                                box-shadow: 0 4px 6px rgba(0,0,0,0.1);
-                            " onmouseover="this.style.background='rgba(0, 0, 0, 0.3)'; this.style.borderColor='rgba(255, 255, 255, 0.2)'"
-                                onmouseout="this.style.background='rgba(0, 0, 0, 0.2)'; this.style.borderColor='rgba(255, 255, 255, 0.1)'">
+                            <div @click="copy(link)" class="subscription-link-box">
                                 [[ link ]]
                                 [[ link ]]
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
+
                     </div>
                     </div>
                     <br />
                     <br />