Handle Connection State Changes
Problem
You need to show connection status in your UI, disable controls while offline, or trigger logic when the client reconnects.
Solution
Subscribe to the connection state observable/stream and react to each state transition.
Code
typescript
import { StarfishClient } from "@starfish/sdk";
const client = new StarfishClient({
server: "ws://localhost:4000",
reconnect: { enabled: true },
});
client.connectionState$.subscribe((state) => {
switch (state) {
case "disconnected":
showBanner("Disconnected");
disableControls();
break;
case "connecting":
showBanner("Connecting...");
break;
case "connected":
hideBanner();
enableControls();
break;
case "reconnecting":
showBanner("Reconnecting...");
disableControls();
break;
}
});
await client.connect();python
from starfish import StarfishClient, StarfishClientOptions, ReconnectOptions, ConnectionState
client = StarfishClient(StarfishClientOptions(
server="ws://localhost:4000",
reconnect=ReconnectOptions(enabled=True),
))
def on_state_change(state: ConnectionState):
if state == ConnectionState.DISCONNECTED:
show_banner("Disconnected")
disable_controls()
elif state == ConnectionState.CONNECTING:
show_banner("Connecting...")
elif state == ConnectionState.CONNECTED:
hide_banner()
enable_controls()
elif state == ConnectionState.RECONNECTING:
show_banner("Reconnecting...")
disable_controls()
client.connection_state.subscribe(on_state_change)
await client.connect()swift
import StarfishClient
let client = StarfishClient(options: StarfishClientOptions(
server: URL(string: "ws://localhost:4000")!,
reconnect: ReconnectOptions(enabled: true)
))
Task {
for await state in client.connectionState {
switch state {
case .disconnected:
showBanner("Disconnected")
disableControls()
case .connecting:
showBanner("Connecting...")
case .connected:
hideBanner()
enableControls()
case .reconnecting:
showBanner("Reconnecting...")
disableControls()
}
}
}
try await client.connect()Explanation
The connection lifecycle has four states:
disconnected → connecting → connected
↑ ↓
reconnecting ←─────┘ (on connection loss)disconnected— not connected and not trying. This is the initial state and the state after callingdisconnect()or exhausting all retries.connecting— establishing the initial connection.connected— fully connected and ready to send/receive.reconnecting— lost connection, attempting to reconnect. With reconnection enabled, the client will retry with exponential backoff.
The observable/stream fires on every transition, so you can update your UI or pause operations accordingly.
Variations
Read the current state synchronously
typescript
// Access the current value without subscribing
const currentState = client.connectionState$.value;
if (currentState === "connected") {
client.publish("chat", { text: "I'm online!" });
}python
# Access the current value without subscribing
current_state = client.connection_state.value
if current_state == ConnectionState.CONNECTED:
await client.publish("chat", {"text": "I'm online!"})swift
// Use the observable's current value
// Note: In Swift, check the stream for the latest state
// or maintain your own @Published property from the streamGuard actions behind connection state
typescript
function safeSend(client, to, payload) {
if (client.connectionState$.value !== "connected") {
console.warn("Not connected — message not sent");
return;
}
client.send(to, payload);
}python
async def safe_send(client, to, payload):
if client.connection_state.value != ConnectionState.CONNECTED:
print("Not connected — message not sent")
return
await client.send(to, payload)swift
func safeSend(_ client: StarfishClient, to: String, payload: AnyCodable) {
do {
try client.send(to: to, payload: payload)
} catch {
print("Not connected — message not sent")
}
}