Keepalive
The client runs an application-level ping/pong on the open socket. If pongs stop coming back it treats the connection as dead and tears it down, which kicks off a reconnect. A single dropped pong is tolerated, so a brief network blip doesn’t cause a needless reconnect. This is layered on top of the server’s own connection-level keepalive — see Connection lifecycle.Reconnect with resubscribe
When the socket closes unexpectedly, the client reconnects with exponential backoff and jitter, emitting areconnecting
event before each attempt:
subscriptionIds are scoped to a single connection and don’t
survive a reconnect, so the client replays your active subscriptions — the
(market, channel) pairs you asked for — on every new connection. You’ll receive
a fresh subscribed ack and a new snapshot for each. Because resubscribe is
automatic, subscriptions you create before the socket is even open are honored too
(they’re sent once the connection is ready).
The backoff budget resets only once a connection is confirmed by a welcome
frame — so a transient drop after a healthy session gets the full retry budget,
while an endpoint that never establishes a session is bounded (see below).
Subscriptions the server permanently retires are not replayed: a status
frame with state: "closed" or "unsupported", or an error frame rejecting a
market at subscription time, prunes that entry so it isn’t retried on reconnect.
goodbye and terminal disconnects
Before closing a connection the server sends a goodbye
frame with a reason. The client treats these two ways:
- Recoverable —
shutdown,ttl,idleTimeout, andnoActiveSubs(when you still have subscriptions to replay). The client reconnects normally. - Terminal —
authRevokedandkicked(andnoActiveSubswhen there’s nothing left to resubscribe). Reconnecting with the same key would be futile, so the client stops.
terminated event. This also fires if
reconnecting repeatedly fails without ever establishing a session (e.g. a bad
stream key or an unreachable endpoint), instead of looping forever.
terminated is final: that client will not reconnect. A fresh client starts with
none of your handlers or subscriptions, so wrap setup in a start function that
creates the client, registers handlers, and subscribes — then call it both
initially and from the terminated handler to resume:
Closing intentionally
Callingclose() yourself is not a disconnect the client recovers from — it
closes the socket and stops all reconnect attempts. Use it on shutdown or when
you’re done streaming.