Keep a long-running stream healthy: answer pings, reconnect with backoff, and restore your subscriptions and local state after every reconnect. A client that only handles onopen and onmessage works in a demo; a stream you rely on also handles onerror, onclose, gaps, and a slow consumer.
What the server expects
Ping loop
Give each socket instance its own ping interval, reconnect timer, and close handler. A timer left running from an old socket sends duplicate pings, opens a second reconnect loop, or restores subscriptions twice.
Reconnect sequence
Stop the old socket's timers
Clear the ping interval and any pending reconnect timer attached to the closed socket.
Wait with capped backoff and jitter
Random jitter keeps many clients from reconnecting at the same moment. Stop after your retry budget and surface the failure instead of retrying forever.
Open a new socket
Authenticate the new connection the same way as the first, with the key kept on the server.
Restore subscriptions from tracked state
Recreate only the channel-symbol pairs your client recorded as active, and only after the new socket opens.
Rebuild unsafe state
For a local book, replay output, or alert state, load a fresh snapshot or replay checkpoint before trusting the output again.
Log the close code, reason, retry count, channel set, and restored symbols on every reconnect, so normal network churn is easy to tell apart from an auth failure, rate pressure, or a broken consumer.
Watch backpressure too
A healthy ping loop does not mean the stream is safe to use. If your message queue keeps growing, the consumer is falling behind. Record queue depth or processing lag beside your reconnect logs, and slow replay or reduce subscriptions when the consumer cannot keep up.
Next step
Size your subscriptions and replay jobs to your plan in WebSocket limits. Last modified on October 6, 2026