Client Handles
Attachments are per-client state. Client handles are the per-socket API actors use to communicate with connected clients.
Client handle operations
Client handles support the core per-socket operations:
yield* client.attachments: read per-socket stateyield* client.send(...): emit an event to one clientyield* client.save(...): persist updated attachment state for that clientyield* client.disconnect: close that client's socket
Actor-wide senders
Actors add whole-actor senders via two groups:
TicTacToeActor.all: every connected clientTicTacToeActor.others: every client other thancurrentClient
Each exposes the same send and disconnect shape:
yield* TicTacToeActor.all.send(...): broadcast to every connected clientyield* TicTacToeActor.all.disconnect: disconnect every connected clientyield* TicTacToeActor.others.send(...): broadcast to everyone except the calling clientyield* TicTacToeActor.others.disconnect: disconnect everyone except the calling client
Broadcast
Effect.gen(function* () {
yield* TicTacToeActor.all.send("GameEnded", { winner: player })
})Selective disconnect
Effect.gen(function* () {
const { clients } = yield* TicTacToeActor
for (const client of clients) {
const { player } = yield* client.attachments
if (bannedPlayers.has(player)) {
yield* client.disconnect
}
}
})Whole-actor disconnect
Effect.gen(function* () {
yield* TicTacToeActor.all.disconnect
})Attachments are not actor storage
client.save(...) updates serialized attachment state for one connected client.
That is useful for values like:
- the caller's user id
- the caller's role in a game
- per-socket cursors or last-seen sequence numbers
Do not use attachments as whole-actor storage. Persist shared state elsewhere, for example through Effect's
KeyValueStore interface backed by an R2 bucket.