WebSocket server: Broadcasting messages

Chat rooms, live dashboards, and multiplayer games all need one thing: deliver a message from one client to all the others. This example keeps track of connected sockets and broadcasts every message it receives.

Edit on GitHub

All currently connected clients. A Set handles disconnects cleanly.

const clients = new Set<WebSocket>();

function broadcast(message: string) {
  for (const client of clients) {

A socket may be mid-handshake or closing; only send when open.

    if (client.readyState === WebSocket.OPEN)
      client.send(message);
  }
}

Ende.serve((req) => {
  if (req.headers.get("upgrade") !== "websocket")
    return new Response("This endpoint expects a WebSocket", { status: 426 });

  const { response, socket } = Ende.upgradeWebSocket(req);

Register the socket once the connection is established, and clean up when it goes away for any reason.

  socket.onopen = () => {
    clients.add(socket);
    broadcast(`${clients.size} clients connected`);
  };

  socket.onclose = () => {
    clients.delete(socket);
    broadcast(`${clients.size} clients connected`);
  };

Relay each incoming message to everyone, including the sender.

  socket.onmessage = (event) => {
    broadcast(event.data);
  };

  return response;
});

Connect two clients from another terminal and every message appears in both: const ws = new WebSocket("ws://localhost:8000/"); ws.onmessage = (event) => console.log(event.data); ws.onopen = () => ws.send("hello, everyone");

This state lives in one worker. To broadcast across the workers of ende serve --parallel, relay each message through a BroadcastChannel, which reaches the other workers. const relay = new BroadcastChannel("chat"); relay.onmessage = (event) => broadcast(event.data); socket.onmessage = (event) => { broadcast(event.data); relay.postMessage(event.data); }; Separate processes and machines do not share a BroadcastChannel; for those, relay through something external like a Redis channel.

Run this example locally using the Ende CLI:

ende run -N https://docs.ende.sh/examples/scripts/websocket_pubsub.ts

Additional resources