Skip to content

Real-time transports

Backlog Hold'em provides two ways to perform the same room workflow.

HTTP commands with SSE events

This is the frontend default.

  1. Commands are sent as HTTP POST requests.
  2. EventSource opens GET /events/rooms/{code}.
  3. The server sends an authoritative snapshot immediately.
  4. Every mutation publishes another complete public snapshot.
  5. A keepalive comment is sent every 15 seconds.

An SSE event looks like:

text
id: 7
event: room
data: {"code":"A1B2C3","version":7,...}

The event ID is the room version. The current implementation sends a fresh snapshot on connection; it does not retain an event log for replay.

Bidirectional WebSocket

The frontend connects to:

text
/ws/rooms/{code}?participantId={participantId}

Commands use a correlation ID:

json
{
  "kind": "command",
  "type": "vote",
  "id": "client-generated-uuid",
  "payload": { "value": "5" }
}

Supported mutation types are vote, reveal, reset, topic, demo-team, and end. HTTP/SSE clients use the matching POST /api/rooms/{code}/{type} endpoint.

The server responds with a correlated acknowledgement:

json
{
  "kind": "ack",
  "type": "vote",
  "id": "client-generated-uuid",
  "room": { "code": "A1B2C3", "version": 7 }
}

Errors use kind: "error" and an error string. Independent room changes use kind: "event"; the initial state uses kind: "snapshot".

Shared semantics

Both modes invoke the same application methods and publish the same public room representation. Neither adapter receives unrevealed vote values or current-round revision counts. Completed history and an ended session's summary are public to room viewers. This avoids protocol-specific authorization or game logic.

Event hub behavior

The process-local hub maintains subscribers by room code. Each subscriber has a bounded channel. Publication is non-blocking; an update is dropped for a subscriber whose queue is full. Since every event is a complete versioned snapshot, a later update supersedes a dropped one.

Scaling boundary

The current hub works only inside one Go process. Multiple backend replicas would need:

  • a distributed event adapter such as Redis or NATS;
  • sticky connections or shared subscription routing;
  • database optimistic locking or transactions based on room version;
  • an explicit presence/connection model.

Backlog Hold'em project documentation