Комнаты и онлайн-статус
Делим пользователей на группы (комнаты) и показываем, кто сейчас онлайн.
Комната (room) — именованная группа клиентов; broadcast в комнату уходит только её участникам, а не всем подряд.
Зачем комнаты
В реальном приложении бесед много: разные чаты, каналы, игровые сессии. Рассылать каждое сообщение всем подключённым нельзя — люди увидят чужое и сервер захлебнётся. Решение — комнаты: при подключении клиент указывает, в какую комнату входит, и сообщения ходят только внутри неё.
Как устроены комнаты
Сервер хранит, кто в какой комнате. Простейшая модель — словарь «комната → набор клиентов». Концептуально:
// серверная логика (для чтения)
const rooms = new Map(); // имя комнаты -> Set сокетов
function join(room, socket) {
if (!rooms.has(room)) rooms.set(room, new Set());
rooms.get(room).add(socket);
}
function broadcastToRoom(room, text) {
const members = rooms.get(room) || new Set();
for (const client of members) {
if (client.readyState === 1) client.send(text);
}
}Когда приходит сообщение для комнаты general, оно уходит только её участникам.
Онлайн-статус
Кто онлайн — определяется наличием открытого соединения. При connection помечаем пользователя онлайн и рассылаем комнате событие { "type": "join", "user": ... }. При close — помечаем оффлайн и шлём { "type": "leave", "user": ... }. Клиенты обновляют список присутствующих.
{ "type": "presence", "online": ["anna", "ivan", "masha"] }Как работает под капотом
Онлайн-статус «бесплатен» в реалтайме: само наличие живого сокета — это и есть присутствие, в отличие от HTTP, где пришлось бы постоянно опрашивать. Тонкость — один пользователь может открыть несколько вкладок (несколько сокетов). Тогда считают присутствие по пользователю, а не по сокету: оффлайн объявляют, только когда закрылась последняя вкладка. Для этого ведут счётчик соединений на пользователя.
Частые ошибки
- Не чистить пустые комнаты. После ухода всех участников структура должна освобождаться, иначе течёт память.
- Считать пользователя оффлайн при закрытии одной вкладки. Учитывайте все его соединения.
- Доверять комнате из сообщения без проверки прав. Сервер должен проверять, вправе ли клиент писать в эту комнату.
Итоги
- Комнаты делят клиентов на группы; broadcast уходит только участникам комнаты.
- Сервер хранит соответствие «комната → клиенты» и рассылает внутри неё.
- Онлайн-статус определяется наличием живого соединения и событиями join/leave.
- Учитывайте несколько вкладок одного пользователя и чистите пустые комнаты.