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).
  • Автору сообщение обычно тоже шлют — ради единого порядка ленты.
  • Клиента нужно удалять из списка при закрытии соединения.
Проверьте себя
1. Что такое broadcast в контексте WebSocket-сервера?
AОтвет только отправителю
BРассылка одного сообщения всем подключённым клиентам
CЗакрытие всех соединений
DШифрование канала
2. Что обязательно проверить перед отправкой каждому клиенту при рассылке?
AДлину сообщения
BЧто readyState клиента === OPEN
CIP-адрес клиента
DВерсию протокола