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