Lifecycle¶
This document describes the complete lifecycle of a WebSocket connection: from opening the socket, authenticating, joining rooms, receiving updates, keeping alive with heartbeats, disconnecting, and reconnecting with state recovery.
Reference: connection.md · authentication.md · rooms.md · events/auction.md
The lifecycle at a glance¶
Stage 1 — Connection¶
- The client opens a WebSocket to
wss://api.example.com/ws(TLS, RFC 6455). - The client supplies an access token (header or
bearer.<token>subprotocol) and thewebsocket.v1subprotocol. - The server upgrades the request and verifies the token.
Failure at this stage closes the socket with code 1008 / Authentication failed (see connection.md).
Stage 2 — Authentication¶
- The server decodes the access token and builds a
SocketUser(userId,role,companyId, permissions). - There is no unauthenticated window; the socket is only "open" for processing once the token is valid.
See authentication.md.
Stage 3 — Join rooms¶
After the handshake the client typically:
- subscribes to auctions with
auction.subscribe(joinsauction:<cycleId>), - optionally joins
company:<id>,user:<id>,notifications, oradminswithroom.join.
The server authorizes each join; disallowed joins return FORBIDDEN.
Stage 4 — Receive updates¶
auction.subscribetriggersauction.connected,auction.snapshot, andpresence.snapshot.- Live bids, presence transitions, and state changes arrive as server-pushed events (see events/auction.md).
- The client applies the snapshot as a base and then the deltas.
Stage 5 — Heartbeat¶
- The server sends protocol
pingevery 20 s; clients auto-answerpong. - Missed pong → the server terminates the connection (see connection.md).
Stage 6 — Disconnect¶
On close/error, the server:
- stops the heartbeat,
- runs every subscription cleanup (unsubscribe from realtime + presence leave),
- leaves all rooms,
- removes the connection from the connection manager,
- logs the closure.
All server-side state tied to the connection is released automatically.
Stage 7 — Reconnect¶
The client reconnects with a fresh token and restores state:
- Open a new socket.
- Re-
auction.subscribewithlastSequenceto replay missed events. - Re-join rooms.
- Apply the new
auction.snapshot.
Sequence diagram¶
sequenceDiagram
participant C as Client
participant S as WebSocket Server
participant R as Redis Pub/Sub
Note over C,S: CONNECT
C->>S: WS upgrade + token (websocket.v1, bearer.<token>)
alt valid token
S-->>C: 101 Switching Protocols
else invalid token
S--xC: close 1008
end
Note over C,S: AUTHENTICATED
C->>S: auction.subscribe { cycleId, lastSequence? }
S->>S: authorize + join auction:<cycleId>
S->>R: ensure ws:room:auction:<cycleId>
S-->>C: auction.connected
S-->>C: auction.snapshot
S-->>C: presence.snapshot
S-->>C: ack
Note over C,S: UPDATES
loop live events
R--)S: ws:room:auction:<cycleId>
S-->>C: bid.created / auction.started / presence.joined ...
end
Note over C,S: HEARTBEAT
loop every 20s
S-->>C: ping
C-->>S: pong
end
Note over C,S: DISCONNECT
alt network failure / close
C--xS: close
S->>R: unsubscribe channel when room empty
S->>S: cleanup rooms + presence + heartbeat
end
Note over C,S: RECONNECT
C->>S: reconnect with fresh token
C->>S: auction.subscribe { cycleId, lastSequence }
S-->>C: auction.snapshot (+ replayed events) State transitions¶
| State | Entered when | Actions | Exit |
|---|---|---|---|
connecting | client opens socket | — | authenticating or closed (handshake fail) |
authenticating | upgrade request received | verify token | open or closed (code 1008) |
open | token valid | register connection, start heartbeat | closing / closed |
subscribed | first room/auction join | join rooms, subscribe redis, presence join | open (on unsubscribe) |
closing | client/server close | run subscription cleanup | closed |
closed | socket closed | remove connection, leave rooms, stop heartbeat | — (may reconnect) |
Resource cleanup checklist (server)¶
| Resource | Released on |
|---|---|
| Heartbeat timer | connection close |
| Room memberships | connection close |
Redis ws:room:<room> subscription | when the room has no members |
| Auction realtime subscription | connection close / auction.unsubscribe |
| Presence (subscriber) | last connection for the enrollment leaves |
| Connection registry entry | connection close |
Reconnect checklist (client)¶
- Refresh the access token (REST refresh endpoint).
- Open a fresh socket with the new token.
- For each active auction:
auction.subscribewithlastSequence= last seenserverSequence. - Rejoin
company:<id>,user:<id>,notifications,adminsas needed. - Discard any in-flight unacknowledged commands with the same
idempotencyKeysemantics; reuse keys so replays are safe.
Related documents¶
- connection.md — transport, heartbeat, reconnection.
- events/auction.md — subscribe/unsubscribe and snapshot/replay.
- diagrams.md — connection lifecycle and reconnection diagrams.