Skip to content

Real Time Updates

amalps565 edited this page Sep 30, 2026 · 2 revisions

Real-Time Updates

STOMP over WebSocket at /ws, published by the backend after each commit and applied by the frontend store.

Transport

  • STOMP over WebSocket, handled by Spring's WebSocket support on the server and @stomp/stompjs in the browser.
  • Endpoint: /ws, plain WebSocket with no SockJS. The Vite dev server proxies it to the backend.
  • Auth: send Authorization: Bearer <jwt> as a STOMP CONNECT header. A CONNECT without a valid JWT gets an ERROR frame and is closed.
  • Clients may only SUBSCRIBE to /topic/floors/{floorId}/{date}; SEND is rejected. Heartbeats run every 10 seconds.
  • Topic: /topic/floors/{floorId}/{date}. Clients subscribe to the floor and date they're viewing.

Message

One message per desk change:

{ "deskId": 101, "date": "2026-10-02", "status": "BOOKED", "bookedBy": "Alice Anders", "bookedByUsername": "alice", "seq": 1043 }
  • status is AVAILABLE or BOOKED.
  • bookedBy and bookedByUsername are null when the desk becomes available. Messages carry no bookingId; the frontend looks it up with GET /api/bookings/me when needed.
  • seq comes from the Postgres sequence desk_status_seq, increases for every change to a desk, and equals the seq in the POST /api/bookings response. The frontend marks a desk as yours when bookedByUsername matches the signed-in user.

Server rules

  • Publish only after commit, using @TransactionalEventListener(phase = AFTER_COMMIT). A booking that rolls back, for example on a 409, is never broadcast.
  • Send only the desk that changed, never the whole floor.

Client rules

flowchart TD
    Start([Open floor and date]) --> Snap[GET snapshot]
    Snap --> Sub[Subscribe to topic]
    Sub --> Msg{Update arrives}
    Msg -- "seq > stored seq" --> Apply[Patch that desk]
    Msg -- "seq <= stored seq" --> Drop[Ignore: stale or duplicate]
    Apply --> Msg
    Drop --> Msg
    Sub -. connection lost .-> Stale[Show 'reconnecting', mark map stale]
    Stale --> Re[Reconnect]
    Re --> Snap
Loading
  1. Load, then subscribe. Load the snapshot, then apply updates.
  2. Drop old updates. Keep the latest seq per desk and ignore any update with a seq that isn't greater. This handles messages that arrive out of order or twice.
  3. Resync after reconnecting. Updates sent while the connection was down are lost, so reload the snapshot every time the socket reconnects.
  4. Show when the map is stale. While disconnected, show a clear indicator.
  5. Clean up. Unsubscribe when the floor or date changes, and when the page unmounts.

Updates can arrive during the snapshot request. Subscribe first and buffer messages until the snapshot arrives, then apply the buffered ones using the seq rule. Nothing is lost that way.

Clone this wiki locally