Re-pairing When a Peer Disconnects
Problem
Two clients were matched into a session, but one disconnects mid-session. You want the remaining client to automatically find a new partner instead of being left alone.
Solution
Watch the session's peer list. When your partner leaves and the peer count drops to zero, leave the now-empty session and re-enter the pool. The server treats each enter as a fresh queue entry, so you'll be matched with the next available client.
Code
typescript
import { StarfishClient } from "@starfish/client";
const client = new StarfishClient({ server: "ws://localhost:4000" });
await client.connect();
const POOL = "duets";
const enterOptions = { groupSize: 2, mode: "auto" as const, create: true };
// Join each matched session as it arrives.
client.pool.matched$.subscribe(async ({ session }) => {
await client.join(session);
});
// If our partner disconnects, leave the empty session and re-enter the pool.
client.peers$.subscribe(async (peers) => {
if (client.clientId && peers.length === 0 && inMatchedSession()) {
await client.leave(); // leave the empty session
await client.pool.enter(POOL, enterOptions); // queue up again
}
});
// No lobby needed — matchmaking precedes session membership.
await client.pool.enter(POOL, enterOptions);python
from starfish import StarfishClient, StarfishClientOptions, PoolEnterOptions
client = StarfishClient(StarfishClientOptions(server="ws://localhost:4000"))
await client.connect()
POOL = "duets"
def enter_options():
return PoolEnterOptions(pool=POOL, group_size=2, mode="auto", create=True)
# Join each matched session as it arrives.
async def on_match(result):
await client.join(result.session)
client.pool_matched.subscribe(on_match)
# If our partner disconnects, leave the empty session and re-enter the pool.
async def on_peers(peers):
if len(peers) == 0 and in_matched_session():
await client.leave()
await client.pool_enter(enter_options())
client.peers.subscribe(on_peers)
# No lobby needed — matchmaking precedes session membership.
await client.pool_enter(enter_options())Explanation
- Leave the old session first. Call
client.leave()before re-entering the pool so you're not still holding a dead session when the new match arrives. - No lobby. Matchmaking precedes session membership, so you enter the pool directly — there's no staging session to join or leave first.
- Each
pool.enter/pool_enteris an independent queue entry — the server has no memory of your previous match, so re-entering simply puts you back in line. - Guard the re-pair logic so it only fires for a genuinely empty matched session, not the moment before your first match. Track a small flag (shown here as
inMatchedSession()/in_matched_session()) that you set when you join a matched session. - A disconnecting peer triggers a peer-list update; the same code path handles a partner who leaves voluntarily.
Variations
Confirm before re-pairing
Instead of re-entering immediately, prompt the user or wait a moment in case the partner reconnects.
typescript
client.peers$.subscribe(async (peers) => {
if (peers.length === 0 && inMatchedSession()) {
const again = await askUser("Your partner left. Find someone new?");
if (again) {
await client.leave();
await client.pool.enter("duets", { groupSize: 2, mode: "auto", create: true });
}
}
});Limit re-pairing attempts
Keep a counter and stop after a few tries so a client doesn't loop forever in an empty pool.
typescript
let attempts = 0;
client.peers$.subscribe(async (peers) => {
if (peers.length === 0 && inMatchedSession() && attempts < 3) {
attempts++;
await client.leave();
await client.pool.enter("duets", { groupSize: 2, mode: "auto", create: true });
}
});