Browse Source

Fixed websocket bug

Martin Ziegler 5 months ago
parent
commit
b642644cbb

+ 8 - 2
backend/app/api/routes/websocket.py

@@ -1,16 +1,19 @@
+import logging
 from fastapi import APIRouter, WebSocket, WebSocketDisconnect
 
 from backend.app.core.websocket import ws_manager
 from backend.app.services.printer_manager import printer_manager, printer_state_to_dict
 
-
+logger = logging.getLogger(__name__)
 router = APIRouter()
 
 
 @router.websocket("/ws")
 async def websocket_endpoint(websocket: WebSocket):
     """WebSocket endpoint for real-time updates."""
+    logger.info("WebSocket client connecting...")
     await ws_manager.connect(websocket)
+    logger.info("WebSocket client connected")
 
     try:
         # Send initial status of all printers
@@ -21,6 +24,7 @@ async def websocket_endpoint(websocket: WebSocket):
                 "printer_id": printer_id,
                 "data": printer_state_to_dict(state),
             })
+        logger.info(f"Sent initial status for {len(statuses)} printers")
 
         # Keep connection alive and handle incoming messages
         while True:
@@ -43,6 +47,8 @@ async def websocket_endpoint(websocket: WebSocket):
                         })
 
     except WebSocketDisconnect:
+        logger.info("WebSocket client disconnected normally")
         await ws_manager.disconnect(websocket)
-    except Exception:
+    except Exception as e:
+        logger.error(f"WebSocket error: {e}", exc_info=True)
         await ws_manager.disconnect(websocket)

+ 8 - 0
backend/app/main.py

@@ -81,8 +81,16 @@ def register_expected_print(printer_id: int, filename: str, archive_id: int):
     )
 
 
+_last_status_broadcast: dict[int, str] = {}
+
 async def on_printer_status_change(printer_id: int, state: PrinterState):
     """Handle printer status changes - broadcast via WebSocket."""
+    # Only broadcast if something meaningful changed (reduce WebSocket spam)
+    status_key = f"{state.connected}:{state.state}:{state.progress}:{state.layer_num}"
+    if _last_status_broadcast.get(printer_id) == status_key:
+        return  # No change, skip broadcast
+    _last_status_broadcast[printer_id] = status_key
+
     await ws_manager.send_printer_status(
         printer_id,
         printer_state_to_dict(state, printer_id),

+ 12 - 7
frontend/src/hooks/useWebSocket.ts

@@ -23,18 +23,17 @@ export function useWebSocket() {
 
     const ws = new WebSocket(wsUrl);
 
+    let pingInterval: number | null = null;
+
     ws.onopen = () => {
+      console.log('[WebSocket] Connected');
       setIsConnected(true);
       // Start ping interval
-      const pingInterval = setInterval(() => {
+      pingInterval = window.setInterval(() => {
         if (ws.readyState === WebSocket.OPEN) {
           ws.send(JSON.stringify({ type: 'ping' }));
         }
       }, 30000);
-
-      ws.onclose = () => {
-        clearInterval(pingInterval);
-      };
     };
 
     ws.onmessage = (event) => {
@@ -46,7 +45,12 @@ export function useWebSocket() {
       }
     };
 
-    ws.onclose = () => {
+    ws.onclose = (event) => {
+      console.log('[WebSocket] Closed', event.code, event.reason);
+      if (pingInterval) {
+        clearInterval(pingInterval);
+        pingInterval = null;
+      }
       setIsConnected(false);
       wsRef.current = null;
 
@@ -56,7 +60,8 @@ export function useWebSocket() {
       }, 3000);
     };
 
-    ws.onerror = () => {
+    ws.onerror = (error) => {
+      console.error('[WebSocket] Error', error);
       ws.close();
     };
 

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-BS0vyekL.js


+ 1 - 1
static/index.html

@@ -7,7 +7,7 @@
     <link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png" />
     <link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png" />
     <link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png" />
-    <script type="module" crossorigin src="/assets/index-C7e8XOql.js"></script>
+    <script type="module" crossorigin src="/assets/index-BS0vyekL.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-CJ8fGWbx.css">
   </head>
   <body>

Some files were not shown because too many files changed in this diff