Browse Source

测试环境wss配置,解决刷新连接问题

LuTong 1 day ago
parent
commit
b3c9a9c924
1 changed files with 26 additions and 3 deletions
  1. 26 3
      src/stores/modules/websocket.ts

+ 26 - 3
src/stores/modules/websocket.ts

@@ -17,11 +17,19 @@ export const useWebSocketStore = defineStore("websocket", () => {
   /** 以底层 readyState 为准,避免 isConnected 与真实连接短暂不一致 */
   const isSocketOpen = () => !!socket.value && socket.value.readyState === WebSocket.OPEN;
 
+  /** 上一笔尚未结束的 connect 的 resolve;刷新时 Header 与聊天页并发 connect 会顶替,必须结束旧 Promise */
+  let pendingConnectResolve: ((ok: boolean) => void) | null = null;
+
   const connect = (url: string): Promise<boolean> => {
     if (isSocketOpen() && lastConnectedUrl.value === url) {
       isConnected.value = true;
       return Promise.resolve(true);
     }
+    if (pendingConnectResolve) {
+      const prev = pendingConnectResolve;
+      pendingConnectResolve = null;
+      prev(false);
+    }
     if (socket.value) {
       try {
         socket.value.close();
@@ -36,17 +44,27 @@ export const useWebSocketStore = defineStore("websocket", () => {
     lastConnectedUrl.value = url;
 
     return new Promise(resolve => {
+      pendingConnectResolve = resolve;
+      const settle = (ok: boolean) => {
+        if (pendingConnectResolve === resolve) {
+          pendingConnectResolve = null;
+          resolve(ok);
+        }
+      };
+
       try {
         const ws = new WebSocket(url);
         socket.value = ws;
 
         ws.onopen = () => {
+          if (socket.value !== ws) return;
           isConnected.value = true;
           isConnecting.value = false;
-          resolve(true);
+          settle(true);
         };
 
         ws.onmessage = (event: MessageEvent) => {
+          if (socket.value !== ws) return;
           try {
             const message = JSON.parse(event.data);
             const category = message.category || "message";
@@ -70,21 +88,26 @@ export const useWebSocketStore = defineStore("websocket", () => {
         };
 
         ws.onclose = () => {
+          // 必须校验实例:新 connect 关闭旧 socket 后,旧 onclose 仍会触发,否则会清空新连接导致「刷新后必现失败」
+          if (socket.value !== ws) return;
           isConnected.value = false;
           isConnecting.value = false;
           socket.value = null;
+          // 握手未完成即关闭时结束 Promise(若已成功 onopen 已 settle,此处不再 resolve)
+          settle(false);
         };
 
         ws.onerror = () => {
+          if (socket.value !== ws) return;
           isConnected.value = false;
           isConnecting.value = false;
           socket.value = null;
-          resolve(false);
+          settle(false);
         };
       } catch (e) {
         console.error("WebSocket 连接异常:", e);
         isConnecting.value = false;
-        resolve(false);
+        settle(false);
       }
     });
   };