Appearance
Connection and recovery
Networks drop, laptops sleep, phones change from Wi-Fi to mobile data, servers restart. The SDK recovers from all of these on its own. Your UI's job is to tell the user what state things are in, in your own words, and to stay out of the way.
One state
The client has exactly one connection state, client.connectionState, announced by the connectionState event (and useConnection() in React):
| State | Meaning | A UI typically… |
|---|---|---|
idle | Not connected yet. | shows nothing |
connecting | The first connect is in progress. | shows nothing, or a spinner on the call button |
connected | Connected; calls and rooms work. | shows nothing |
reconnecting | The connection was lost and the SDK is getting it back. | shows a banner: "Reconnecting…" |
closed | Closed by close(), or the SDK has given up. | shows an offline state with a way to try again |
There is one state because there is one controller: whether the socket dropped, the server stopped answering, or the media stopped flowing, "reconnecting" means the same thing and a banner can trust it. While reconnecting, connectionState's second argument says why — cause is socket_closed, no_pong, media_failed or server_shutdown — and which attempt this is, for logs or a more specific message.
ts
client.on('connectionState', (state, { cause, attempt }) => {
banner.show(state === 'reconnecting');
log.info('talkline', { state, cause, attempt });
});What recovers by itself
The connection to the signaling server. When the socket closes or the server stops answering for 20 seconds, the SDK reconnects with backoff — half a second, then 1, 2, 4 and 8 seconds, with jitter — asking your token provider for a new token each time. A provider that throws only fails that attempt: the SDK backs off and asks again (The web SDK). The session survives fifteen minutes without a connection: a client back within that time resumes exactly where it was, in the same room and the same call, and the others in the room see nothing but a short freeze.
The media. When media stops flowing — the network path changed, a firewall closed a port — the SDK climbs a ladder: first an ICE restart, then a rebuilt connection, then a rebuilt connection through a TURN relay. Each step is announced by mediaRecovery ({ step, of }), for a UI that wants to say "still trying". The ladder stops as soon as media flows again.
A server failing. A room on a media server that fails is moved to another, and every client in it is moved with it. The call continues.
When it gives up
- After fifteen minutes without getting back, the session is gone. The SDK stops, the state becomes
closed, anderrorfires withsession_expired. - When the server refuses the credential — the token is invalid, the application is suspended, the build is too old — reconnecting would fail the same way forever, so the SDK stops at once and raises that code:
unauthenticated,token_expired,token_replayed,permission_denied,app_suspended,duplicate_identity,quota_exhausted,client_outdatedortoken_required. - When the media ladder runs out, the call ends — the other side is told — with
media_failed. The connection stays up, and the next call starts fresh.
To try again after the SDK has given up — a button in your offline state — call client.connect(): it starts a new session with a new token. Only a client you closed yourself with close() cannot be connected again.
Audio the browser will not play
Browsers — Safari especially — refuse to play audio that no user gesture led to. When that happens the SDK raises needsUserGesture, and keeps the audio ready. Show a button; its click handler calls client.resumeAudio(). In React, useAudioPlayback() gives you { blocked, resume }.
When the server ends the session
disconnected fires with { reason, reconnectAllowed } when the server closes the session on purpose — the user was removed, or their identity's credit ran out. When reconnectAllowed is false, the SDK does not try again.
Keeping an old app working
Talkline supports old builds of your app for a long time, and tells you before it stops: updateDue fires when this build's SDK is getting old for the deployment, while it is still fully served. Use it to nudge users to update. Compatibility.