فهرست منبع

fix: improve WebSocket resilience, dynamic URL detection and logging

unknown 2 ماه پیش
والد
کامیت
5b3a4e5368
4فایلهای تغییر یافته به همراه26 افزوده شده و 7 حذف شده
  1. 2 0
      backend/main.py
  2. 3 3
      src/components/OrderChat.vue
  3. 18 1
      src/lib/utils.ts
  4. 3 3
      src/stores/auth.ts

+ 2 - 0
backend/main.py

@@ -90,11 +90,13 @@ app.include_router(warehouse.router)
 async def ws_global(websocket: WebSocket, token: str = Query(...)):
     payload = auth_utils.decode_token(token)
     if not payload:
+        print(f"DEBUG: WS Global Auth failed for token: {token[:10]}...")
         await websocket.close(code=4001)
         return
     user_id = payload.get("id")
     role = payload.get("role")
     if not user_id:
+        print(f"DEBUG: WS Global Auth failed: no user_id in payload")
         await websocket.close(code=4001)
         return
         

+ 3 - 3
src/components/OrderChat.vue

@@ -137,9 +137,9 @@ let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
 function connectWebSocket() {
   const token = localStorage.getItem("token");
   if (!token) return;
-
-  const WS_BASE_URL = getWsUrl();
-  ws = new WebSocket(`${WS_BASE_URL}/chat?token=${encodeURIComponent(token)}&order_id=${props.orderId}`);
+  const url = `${getWsUrl()}/chat?token=${encodeURIComponent(token)}&order_id=${props.orderId}`;
+  console.log("DEBUG: Connecting Order Chat WS to:", url);
+  ws = new WebSocket(url);
 
   ws.onopen = () => {
     wsConnected.value = true;

+ 18 - 1
src/lib/utils.ts

@@ -11,5 +11,22 @@ export function getWsUrl() {
   
   const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
   const host = window.location.host;
-  return `${protocol}//${host}`;
+  
+  // Try to derive path prefix from VITE_API_URL if it's a relative-looking path on the same host
+  // or a full URL on the same host.
+  const apiUrl = import.meta.env.VITE_API_URL || "";
+  let pathPrefix = "";
+  
+  try {
+    if (apiUrl.startsWith('http')) {
+      const url = new URL(apiUrl);
+      if (url.host === host) {
+        pathPrefix = url.pathname.replace(/\/$/, '');
+      }
+    } else if (apiUrl.startsWith('/')) {
+      pathPrefix = apiUrl.replace(/\/$/, '');
+    }
+  } catch (e) {}
+
+  return `${protocol}//${host}${pathPrefix}`;
 }

+ 3 - 3
src/stores/auth.ts

@@ -21,7 +21,6 @@ export const useAuthStore = defineStore("auth", () => {
       );
     } catch {
       user.value = null;
-      wsAuthFailed.value = true;
       showCompleteProfile.value = false;
       stopPing();
     } finally {
@@ -35,7 +34,6 @@ export const useAuthStore = defineStore("auth", () => {
 
   let globalWs: WebSocket | null = null;
   let reconnectTimer: number | null = null;
-  const WS_BASE_URL = getWsUrl();
 
   // ── Audio ──────────────────────────────────────────────────────────────────
   // Single shared AudioContext, created lazily on first user gesture.
@@ -141,7 +139,9 @@ export const useAuthStore = defineStore("auth", () => {
     stopPing(); // Ensure fresh start
     const token = localStorage.getItem("token");
     if (!token || wsAuthFailed.value) return;
-    globalWs = new WebSocket(`${WS_BASE_URL}/global?token=${encodeURIComponent(token)}`);
+    const url = `${getWsUrl()}/global?token=${encodeURIComponent(token)}`;
+    console.log("DEBUG: Connecting Global WS to:", url);
+    globalWs = new WebSocket(url);
 
     globalWs.onopen = () => {
       // Send ping every 25 seconds to keep connection alive and update online status in Redis