Skip to main content

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.

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);
    }
  }
}

Deno.serve((req) => {
  if (req.headers.get("upgrade") !== "websocket") {
    return new Response("This endpoint expects a WebSocket", { status: 426 });
  }
  const { socket, response } = Deno.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 deno serve --parallel, relay each message through a BroadcastChannel, which reaches the other workers; on Deno Deploy it reaches the other instances too. 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 Deno KV watch or a Redis channel.

Run this example locally using the Deno CLI:

deno run -N https://docs.deno.com/examples/scripts/websocket_pubsub.ts

Did you find what you needed?

Privacy policy