connectedClients / ConnectedClient

Documentation for Redweb 0.16.1. Install that exact version when following these examples.

Route-owned connected players with checked identity, bounded room membership, deduplicated presence and private server-page updates. Reuses RoomRegistry; no second socket map or browser dispatcher is required.

Explain it like I’m five

Each player gets a checked name badge and a private screen. Redweb tracks who is connected and updates their screens; your game still decides what each person may do and see.

When should I use it?

Use it with socket-bound TSX pages to remove manual membership maps, identity rechecks, presence loops and fan-out code. Ordinary raw socket routes need not adopt it.

Follow the example

This API pattern illustrates the named surface; it may require application-owned classes, credentials, or assets. Start from a complete recipe for a runnable application.

ts
import { connectedClients } from 'redweb'

// Supply your authenticated account lookup, game service, page and contract.
const players = connectedClients({
  identity: context => account(context.request),
  page: () => GamePage,
  project: (player, room, online) => ({
    game: games.resume(room, player.identity).snapshot(player.identity),
    online,
  }),
})
const match = players.bind(contract)
const Join = match.handler('join', (player, { room }) =>
  player.join(room, () => games.join(room, player.identity)))

// Register connections: players and protocol: match.protocol on MatchRoute.
// Attach GamePage with @page('/', { socket: MatchRoute }).
// Its TSX form uses rw-submit={Join}.
  1. Create a fresh group inside the application factory and register it with one SocketRoute.
  2. Bind typed handlers and use their classes in TSX controls; connect the page to that route.
  3. After successful commands and membership changes, Redweb projects each player’s permitted state and discards obsolete results.

Options

  • identity: rechecks the admitted principal against current credentials
  • page: lazy reference to the attached page class
  • project: side-effect-free per-player page state; online identities are deduplicated
  • reject / errorState: classify deliberately public errors and map them to page fields
  • raw: optional update/reject adapters for non-HTML clients
  • authorizationTimeoutMs / projectionTimeoutMs: bounded asynchronous work

Methods and members

players.bind(contract)

Creates typed handlers whose callback receives a ConnectedClient; successful commands refresh its rooms.

players.get(socket)

Returns the checked route-owned facade for page connection lifecycle hooks.

players.refresh(room)

Projects external domain changes to that room’s currently authorized connections.

player.identity / page / rooms / room

Admitted identity, private page, membership snapshot, and exactly-one-room convenience accessor.

player.join(room, commit?) / leave(room)

Checks capacity and authorization before a synchronous domain commit; failure removes newly added membership, not arbitrary domain side effects.

What should I watch for?

Create one group per route instance. Identity must match the admitted principal. Applications still own room authorization, game rules, transactions, seat recovery and persistence. Raw state events are uncorrelated; request completion uses redweb:result. Never send inside projection adapters.