patterntypescriptModerate
Room-Based Architecture Requires Deterministic Room ID Generation
Viewed 0 times
room IDroom architecturemultiplayerWebSocket roomsnamespacedeterministic IDcollaboration rooms
Problem
In a room-based multiplayer system, two users intending to join the same collaborative session end up in different rooms because the room ID is generated client-side with no coordination.
Solution
Derive the room ID from a canonical resource identifier (document ID, entity ID) rather than generating it randomly per session. The room ID is a function of what is being collaborated on, not of who is joining.
// Room ID derived from document — both users compute the same ID
function getRoomId(documentId: string, orgId: string): string {
return `${orgId}:doc:${documentId}`;
}
// Server: join or create room
wss.on('connection', (ws, req) => {
const { roomId, userId } = parseQuery(req.url);
if (!rooms.has(roomId)) {
rooms.set(roomId, new Set());
}
const room = rooms.get(roomId)!;
room.add({ ws, userId });
ws.on('close', () => {
room.delete({ ws, userId });
if (room.size === 0) rooms.delete(roomId);
});
});Why
Rooms are a server-side routing mechanism for grouping connections. If the ID is random, users have no deterministic way to land in the same room. Deriving the ID from the shared resource makes it naturally consistent.
Gotchas
- Include a tenant/org namespace in the room ID to prevent cross-tenant data leakage.
- Validate room ID access server-side — any client can construct any room ID and try to join.
- Clean up empty rooms to prevent memory leaks on the server.
- For private rooms (DMs), hash the sorted user IDs: SHA256(sort([uid1, uid2]).join(':'))
Revisions (0)
No revisions yet.