Skip to content

Connection

This document describes how to establish and maintain a Dichit WebSocket connection: the endpoint, TLS, reconnection strategy, timeouts, heartbeats, compression, and message-size limits.

Reference: README.md · protocol.md · authentication.md · lifecycle.md


Connection endpoint

One endpoint serves every role:

Production:   wss://api.example.com/ws
Staging:      wss://api.staging.example.com/ws
Local dev:    ws://localhost:3500/ws

Rules:

  • The path is /ws. Other paths are not WebSocket routes.
  • wss:// (TLS) is mandatory outside local development.
  • Each connection must present a valid access token during the handshake.
  • A single client may open multiple connections (e.g. one per device). The server tracks connections per user and fans out user-scoped messages to every open connection.

TLS requirements

  • TLS 1.2 or higher.
  • Production and staging endpoints require a valid, publicly trusted certificate.
  • Self-signed certificates are rejected.
  • Clients must verify the certificate chain and hostname.
  • Mobile clients should pin the production certificate only when their app policy requires it; ordinary certificate validation is the default.

Connection handshake

The client opens a WebSocket upgrade request. It must authenticate and declare a supported subprotocol:

GET /ws HTTP/1.1
Host: api.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Protocol: websocket.v1, bearer.<access-token>
Item Requirement
Sec-WebSocket-Version 13
Sec-WebSocket-Protocol At least one of websocket.v1 or auction-room.v1, optionally followed by bearer.<token>.
Authorization Authorization: Bearer <token> header or bearer.<token> subprotocol.

The server accepts the upgrade, verifies the token, and opens the socket. Handshake details are in authentication.md.

Protocol negotiation

  • websocket.v1 — current protocol version (preferred).
  • auction-room.v1 — legacy auction room protocol, accepted for compatibility.
  • bearer.<access-token> — transport for the access token when a custom header cannot be set (e.g. browsers).

The client should always send websocket.v1 (or auction-room.v1) plus bearer.<token>. If only bearer.<token> is sent without a protocol token, the server still accepts the connection.

Subprotocol token transport

Two equivalent ways to authenticate:

Transport When to use Example
Authorization header Native/mobile/backend clients that control HTTP headers Authorization: Bearer <token>
Sec-WebSocket-Protocol: bearer.<token> Browsers and clients that cannot set custom headers Sec-WebSocket-Protocol: websocket.v1, bearer.<token>

If both are present, the Authorization header wins.

Heartbeats

The server maintains liveness with WebSocket protocol-level pings:

  • The server sends a ping control frame every 20000 ms (WEBSOCKET_HEARTBEAT_INTERVAL_MS).
  • The client must respond with a protocol-level pong (browsers and ws auto-respond; most clients handle this transparently).
  • If the server does not receive a pong by the next interval, it terminates the connection.

Clients do not need to send application-level pings. system.ping exists for latency/RTT checks and application-level liveness (see events/system.md).

Client responsibilities

  • Ensure the socket library auto-answers protocol pongs. For raw ws, enable automatic pong handling (default).
  • Do not block the event loop; a blocked client cannot answer pings and will be dropped.
  • Treat a dropped connection as transient and reconnect with backoff.

Timeouts

Timeout Value Behaviour
Heartbeat interval 20 000 ms Server pings the client.
Missed heartbeat 1 interval No pong by the next tick → server terminates the socket.
Connection auth Immediate Token verified during handshake; failure closes with code 1008.
Application-level latency check Optional Use system.ping/system.pong and measure round trip.

There is no server-side idle timeout beyond the heartbeat mechanism: an alive connection can stay open indefinitely.

Maximum message size

  • Maximum payload per frame: 65 536 bytes (WEBSOCKET_CONNECTION_MAX_PAYLOAD_BYTES).
  • Frames larger than the limit fail the connection (policy violation). Keep messages small; big payloads (images, documents) belong on HTTP, not on the socket.

Practical guidance:

  • If a command's data would exceed the limit, split it or move it to REST and push only a reference.
  • Monitor sent message sizes; server events are compact by design.

Compression support

  • The server does not negotiate permessage-deflate by default.
  • Clients should not require compression.
  • Where payloads are large, prefer smaller message shapes over relying on transport compression.

Reconnection strategy

The server may terminate a connection for network loss, redeployments, or heartbeat expiry. Clients must reconnect automatically.

Recommended strategy:

  1. On unexpected close, reconnect immediately.
  2. On failure, back off exponentially: 1 s, 2 s, 4 s, … capped at 30 s, with full jitter.
  3. Reconnect with a fresh access token (refresh via the REST API if needed).
  4. After reconnecting to auction.subscribe, resume from the last serverSequence (pass lastSequence) to receive missed events via replay, or consume the fresh auction.snapshot.
  5. Do not send commands from a dead connection; wait for open.
sequenceDiagram
    participant C as Client
    participant S as Server

    loop Until connected
        C->>S: WebSocket open (wss://.../ws)
        alt Success
            S-->>C: open (authenticated)
            Note over C,S: Ready
        else Failure or close
            S--xC: close / timeout
            C->>C: exponential backoff (1s..30s + jitter)
        end
    end

Close codes

The server uses standard WebSocket close codes:

Code Meaning Client action
1000 Normal closure (client-initiated logout/close). None.
1008 Policy violation — authentication failed. Re-authenticate with a valid token, then reconnect.
1009 Message too big (payload > max). Reduce payload size and resend on a fresh connection.
1001 Going away (e.g. server restart). Reconnect with backoff.

Connection state summary

A connection transitions between connecting, open, closing, and closed. Room memberships, auction subscriptions, and heartbeat timers are torn down when the socket closes. See lifecycle.md.