Match handlers and resumable ownership
Documentation for Redweb 0.13.2. Install that exact version when following these examples.
Give the match its own socket route, then dispatch join, move and resume by type. These canonical socket-starter handlers create and recover server-owned player sessions; they are not a room-broadcast or account-authentication example.
Use the complete socket recipe for setup, files, and tests.
import { randomUUID } from 'node:crypto';
import type { RedWebSocket } from 'redweb';
import { match } from './contract';
class Player {
readonly session = randomUUID();
x = 0;
y = 0;
constructor(readonly name: string) {}
}
function requireUnjoined(socket: RedWebSocket) {
if (socket.context?.session) throw new Error('Already joined.');
}
function currentPlayer(socket: RedWebSocket) {
const session = socket.context?.session as { data?: unknown } | null | undefined;
if (!(session?.data instanceof Player)) throw new Error('Join or resume first.');
return session.data;
}
export const Join = match.handler('join', (socket, { name }, message) => {
requireUnjoined(socket);
const player = new Player(name);
if (!socket.createSession?.(player.session, player)) throw new Error('Session capacity reached.');
return match.send(socket, 'state', player, { requestId: message.requestId });
});
export const Move = match.handler('move', (socket, { x, y }, message) => {
const player = currentPlayer(socket);
player.x = x;
player.y = y;
return match.send(socket, 'state', player, { requestId: message.requestId });
});
export const Resume = match.handler('resume', (socket, { session }, message) => {
requireUnjoined(socket);
if (!(socket.resumeSession?.(session) instanceof Player)) throw new Error('Session expired or unknown.');
return match.send(socket, 'state', currentPlayer(socket), { requestId: message.requestId });
});Notes and boundaries
- Initialize the complete socket recipe: src/contract.ts defines validated payloads and src/app.tsx configures /match, session capacity and transport limits. This file is not a standalone server.
- Join issues a random bearer session token. Move requires an existing player; resume restores that player on a new connection and replaces the previous owner.
- Keep the state response and session token private. Add account authentication and application movement rules before production; sessions remain in memory and expire 30 seconds after disconnect.
- For authenticated group delivery, use the separate One identity for a page and a protected room example. The shared socket contracts guide links its complete source and the room-authorization guide.