websocket.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import logging
  2. from fastapi import APIRouter, WebSocket, WebSocketDisconnect
  3. from backend.app.core.websocket import ws_manager
  4. from backend.app.services.background_dispatch import background_dispatch
  5. from backend.app.services.printer_manager import printer_manager, printer_state_to_dict
  6. logger = logging.getLogger(__name__)
  7. router = APIRouter()
  8. @router.websocket("/ws")
  9. async def websocket_endpoint(websocket: WebSocket):
  10. """WebSocket endpoint for real-time updates."""
  11. logger.info("WebSocket client connecting...")
  12. await ws_manager.connect(websocket)
  13. logger.info("WebSocket client connected")
  14. try:
  15. # Send initial status of all printers
  16. statuses = printer_manager.get_all_statuses()
  17. for printer_id, state in statuses.items():
  18. await websocket.send_json(
  19. {
  20. "type": "printer_status",
  21. "printer_id": printer_id,
  22. "data": printer_state_to_dict(state, printer_id, printer_manager.get_model(printer_id)),
  23. }
  24. )
  25. dispatch_state = await background_dispatch.get_state()
  26. if (dispatch_state.get("dispatched", 0) + dispatch_state.get("processing", 0)) > 0:
  27. await websocket.send_json(
  28. {
  29. "type": "background_dispatch",
  30. "data": dispatch_state,
  31. }
  32. )
  33. logger.info("Sent initial status for %s printers", len(statuses))
  34. # Keep connection alive and handle incoming messages
  35. while True:
  36. data = await websocket.receive_json()
  37. # Handle ping/pong for keepalive
  38. if data.get("type") == "ping":
  39. await websocket.send_json({"type": "pong"})
  40. # Handle status request
  41. elif data.get("type") == "get_status":
  42. printer_id = data.get("printer_id")
  43. if printer_id:
  44. state = printer_manager.get_status(printer_id)
  45. if state:
  46. await websocket.send_json(
  47. {
  48. "type": "printer_status",
  49. "printer_id": printer_id,
  50. "data": printer_state_to_dict(state, printer_id, printer_manager.get_model(printer_id)),
  51. }
  52. )
  53. except WebSocketDisconnect:
  54. logger.info("WebSocket client disconnected normally")
  55. await ws_manager.disconnect(websocket)
  56. except Exception as e:
  57. logger.error("WebSocket error: %s", e, exc_info=True)
  58. await ws_manager.disconnect(websocket)