Skip to content

Reconnect Handling ​

Reconnect is explicit by default. Match sessions can also own retry and heartbeat recovery through autoReconnect, which detects both ordinary socket closes and zombie sockets that still report themselves as open.

Automatic reconnect and heartbeat ​

ts
const 
matchSession
=
simulatorClient
.
session
.
create
(
hostAccess
, {
autoReconnect
: {
initialDelayMs
: 500,
maxDelayMs
: 5_000,
maxRetries
: 180,
heartbeat
: {
intervalMs
: 10_000,
timeoutMs
: 10_000,
}, }, })

With autoReconnect, heartbeat is enabled unless heartbeat: false is set. The session sends a nonce-bearing ping after its socket opens and after each successful pong. If its pong does not arrive before timeoutMs, the SDK closes the stale socket and uses the configured retry backoff. A successful replacement requests an authoritative sync; it does not reconstruct game state from prior events.

The latest snapshot stays available while recovery runs. close() always cancels retries and heartbeat timers.

Basic reconnect ​

ts
// Reconnect closes the old socket, opens a new one, then syncs state.
await 
matchSession
.
reconnect
()

reconnect():

  1. Closes the current socket and detaches its listeners.
  2. Opens a new socket with the same matchId and seatToken.
  3. Waits for the normal welcome + first snapshot.
  4. Sends an explicit syncRequest so the server resends state.

When to call it:

  • The transport dropped (connectionState === 'closed' unexpectedly).
  • The app woke from a long background pause.
  • The user manually requested a reconnect.

Watch for drops ​

ts
matchSession
.
on
('connectionState',
connectionState
=> {
if (
connectionState
=== 'closed') {
// Add your own retry/backoff policy when autoReconnect is disabled. void
matchSession
.
reconnect
()
} })

Wrap this with a debounce, retry counter, and exponential backoff if you need to tolerate flapping networks.

Token invalidation ​

If the server rejects the seat token on reconnect, the handshake fails, reconnect() rejects with an Error, and connectionState becomes closed. In normal operation the token stays valid for the lifetime of the match, so token rejection usually means the match has ended or been evicted. Treat it as a terminal state and re-run the access flow (matches.create() / matches.join()) before trying again.

Preserved state ​

Across a successful reconnect the SDK keeps the last welcome and the latest snapshot it has seen. Listeners registered with on() are not detached. New snapshot and event values arriving after the reconnect flow through the same subscriptions.

Released under the MIT License.