Skip to main content

Connection Lifecycle

Understanding the connection state machine and how to handle state transitions.


Connection States​

StateDescription
disconnectedInitial state, not connected
connectingWebSocket/WebRTC handshake in progress
connectedFully connected, ready for conversation
reconnectingConnection lost, attempting recovery
failedConnection failed after max retries
closedExplicitly closed by user

Connection Flow​


Reconnection​

Automatic reconnection is enabled by default with exponential backoff.

Configuration​

const client = new LLMRTCWebClient({
signallingUrl: 'ws://localhost:8787',
reconnection: {
enabled: true, // Enable auto-reconnect (default: true)
maxRetries: 5, // Max retry attempts (default: 5)
baseDelayMs: 1000, // Initial delay (default: 1000)
maxDelayMs: 30000, // Max delay (default: 30000)
jitterFactor: 0.3 // Randomization factor (default: 0.3)
}
});

Backoff Formula​

delay = min(baseDelayMs * 2^attempt, maxDelayMs) * (1 ± jitterFactor)

Example with defaults:

  • Attempt 1: ~1s
  • Attempt 2: ~2s
  • Attempt 3: ~4s
  • Attempt 4: ~8s
  • Attempt 5: ~16s

Session Recovery​

During reconnection, the client attempts to recover the previous session:


Client Methods​

start()​

Initiate connection:

const client = new LLMRTCWebClient({ signallingUrl: 'ws://localhost:8787' });
await client.start();
// State: connecting → connected

close()​

Clean shutdown:

client.close();
// State: → closed

state​

Get current state:

if (client.state === 'connected') {
// Ready for conversation
}

currentSessionId​

Get session ID (for manual persistence):

const sessionId = client.currentSessionId;
localStorage.setItem('sessionId', sessionId);

Handling State Changes​

const client = new LLMRTCWebClient({ signallingUrl: 'ws://localhost:8787' });

client.on('stateChange', (state) => {
console.log('State:', state);

switch (state) {
case 'connecting':
showStatus('Connecting...');
break;

case 'connected':
showStatus('Connected');
enableMicrophone();
break;

case 'reconnecting':
showStatus('Reconnecting...');
disableMicrophone();
break;

case 'failed':
showStatus('Connection failed');
showRetryButton();
break;

case 'closed':
showStatus('Disconnected');
break;
}
});

client.on('reconnecting', (attempt, maxAttempts) => {
showStatus(`Reconnecting (${attempt}/${maxAttempts})...`);
});

Best Practices​

Show Connection Status​

Always display connection state to users:

function ConnectionBadge({ state }: { state: ConnectionState }) {
const colors = {
disconnected: 'gray',
connecting: 'yellow',
connected: 'green',
reconnecting: 'orange',
failed: 'red',
closed: 'gray'
};

return <Badge color={colors[state]}>{state}</Badge>;
}

Queue Input During Reconnection​

Don't drop user interactions during reconnection:

client.on('stateChange', (state) => {
if (state === 'connected') {
// Ready for interaction
enableMicrophone();
} else if (state === 'reconnecting') {
// Disable input during reconnection
disableMicrophone();
}
});

Persist Session for Page Refresh​

// On connect
client.on('stateChange', (state) => {
if (state === 'connected') {
localStorage.setItem('sessionId', client.currentSessionId);
}
});

// On page load - session restoration happens automatically
// The client will attempt to reconnect with the previous session
await client.start();