How to implement WebSocket rooms for group messaging
room data structure with Map, joining and leaving rooms, per-room broadcast, client metadata, room membership tracking, cleanup on disconnect, room capacity limits
Rooms Are Just Sets of Clients
The ws package has no built-in room concept. Implement rooms with a Map:
const rooms = new Map(); // roomId -> Set of ws clients function joinRoom(ws, roomId) { if (!rooms.has(roomId)) rooms.set(roomId, new Set()); rooms.get(roomId).add(ws); ws.roomId = roomId; // store on client object } function leaveRoom(ws) { const room = rooms.get(ws.roomId); if (room) { room.delete(ws); if (room.size === 0) rooms.delete(ws.roomId); } } function broadcastToRoom(roomId, message, exclude = null) { const room = rooms.get(roomId); if (!room) return; const payload = JSON.stringify(message); for (const client of room) { if (client !== exclude && client.readyState === WebSocket.OPEN) { client.send(payload); } } } wss.on('connection', (ws) => { ws.on('close', () => leaveRoom(ws)); });
Always call leaveRoom in the close handler to prevent stale references. Delete empty rooms immediately to avoid unbounded Map growth in servers with many transient rooms.
