Broadcast: рассылка всем клиентам
Учим сервер хранить всех подключённых и рассылать сообщение каждому.
Broadcast (широковещание) — отправка одного сообщения сразу всем подключённым клиентам (или всем в комнате).
От эха к чату
Эхо-сервер отвечал только отправителю. В чате сообщение одного должны увидеть все. Значит, серверу нужно помнить список всех подключений и при получении сообщения пройтись по нему, отправив каждому.
Список клиентов и рассылка
На Node.js библиотека ws уже хранит набор клиентов в wss.clients. Код серверный, для чтения:
const { WebSocketServer } = require("ws");
const wss = new WebSocketServer({ port: 8080 });
wss.on("connection", (socket) => {
socket.on("message", (data) => {
const text = data.toString();
// рассылаем ВСЕМ подключённым
wss.clients.forEach((client) => {
if (client.readyState === 1) { // 1 = OPEN
client.send(text);
}
});
});
});Теперь сообщение любого участника уходит всем — получился групповой чат.
Схема рассылки
сообщение от Анны
|
v
+--------------+
| СЕРВЕР |
| clients: A B C|
+--------------+
/ | \
v v v
Анне Ивану Маше (всем, включая автора)Себе слать или нет?
Часто автору сообщение тоже отправляют (эхо) — чтобы он увидел его в общей ленте в том же порядке, что и остальные. Иногда автора исключают (client !== socket), если интерфейс уже показал сообщение локально. Это решение протокола.
Как работает под капотом
Сервер держит структуру (множество/массив) со всеми активными сокетами. При подключении сокет добавляется, при close — удаляется. broadcast — это просто цикл с проверкой readyState: закрытым или закрывающимся клиентам слать нельзя. При тысячах клиентов наивный цикл может стать узким местом — тогда применяют комнаты (рассылку только нужной группе) и горизонтальное масштабирование, о которых дальше.
Частые ошибки
- Не удалять клиента при
close. Список распухнет «мертвецами», рассылка будет бить в закрытые сокеты. - Слать без проверки
readyState. Отправка в закрывающийся сокет — ошибка; всегда проверяйте, что он OPEN. - Слать всем то, что должно идти одной группе. Для разных бесед нужны комнаты, иначе все видят чужое.
Итоги
- Для группового чата сервер хранит список всех подключений.
- Broadcast — цикл по клиентам с отправкой каждому (проверяя
readyState). - Автору сообщение обычно тоже шлют — ради единого порядка ленты.
- Клиента нужно удалять из списка при закрытии соединения.