Skip to content

WebSocket Real-time Updates

Endpoint

ws://localhost:8080/ws/notifications?token=<jwt_access_token>

Authentication

The WebSocket connection requires a valid JWT access token as a query parameter.

Invalid or expired tokens result in connection rejection (code 4001).

Connection Example

const ws = new WebSocket("ws://localhost:8080/ws/notifications?token=your_jwt_token");

ws.onopen = () => {
  console.log("Connected to WebSocket");
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Received:", data);
};

ws.onclose = () => {
  console.log("Disconnected");
};

Server Events

After shipment CRUD operations, the server sends JSON messages:

Event Trigger Payload
shipment_created POST /api/shipments Full shipment object
shipment_updated PUT /api/shipments/{id} Full shipment object
shipment_deleted DELETE /api/shipments/{id} {"id": "uuid"}

Example Event

{
  "type": "shipment_created",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "tracking_id": "TRK-A1B2C3D4",
    "sender_name": "Juan Pérez",
    "status": "RECEIVED",
    ...
  }
}

Keepalive

The server responds to ping messages with pong for keepalive:

ws.send("ping");  // Server responds with "pong"

Implementation Files

Component Location
ConnectionManager core/websocket_manager.py
WebSocket Routes modules/notifications/presentation/websocket_routes.py

Reconnection Strategy

ws.onclose = () => {
  setTimeout(() => connect(), 5000); // Retry after 5s
};

Client Library

Use websockets library (NOT httpx for WebSocket):

import websockets

self._ws = await websockets.connect(ws_url)

Frontend Implementation

Connection

async def connect_websocket(page: ft.Page, token: str) -> None:
    ws_client = ServiceLocator.get(WebSocketClient)
    shipments_ctrl = ServiceLocator.get(ShipmentsController)

    success = await ws_client.connect(page, token, config.api_base_url)
    if success:
        shipments_ctrl.setup_websocket_handlers(ws_client)

WebSocket URL

ws://localhost:8000/ws/notifications?token=<jwt_access_token>

Event Handlers

def setup_websocket_handlers(self, ws_client: WebSocketClient) -> None:
    ws_client.on("shipment_created", self._on_shipment_created)
    ws_client.on("shipment_updated", self._on_shipment_updated)
    ws_client.on("shipment_deleted", self._on_shipment_deleted)

Files

  • Client: core/network/websocket_client.py
  • Backend Manager: saas-backend/core/websocket_manager.py
  • Backend Routes: saas-backend/modules/notifications/presentation/websocket_routes.py