Broadcasting is one of the most powerful features of WebSockets, allowing servers to send messages to multiple connected clients simultaneously. Unlike point-to-point communication, where messages are exchanged between a single client and the server, broadcasting enables a single message to reach a group of clients. This makes it indispensable for real-time, collaborative, and interactive applications.
Broadcasting is essential for scenarios where multiple users need to stay synchronized or informed about the same updates in real-time. For example:
In such cases, broadcasting ensures that all connected users are kept in sync without requiring individual server calls for each client, which would otherwise be inefficient and prone to latency.
When implementing broadcasting, there are two common strategies to consider:
This approach sends the message to all clients connected to a specific channel, including the one that originated the message.
This approach is suitable for situations where every client, including the sender, needs to receive the broadcast, such as displaying an acknowledgment or update of their message in a group chat.
In this case, the message is broadcast to all clients except the one who sent it.
This approach is ideal for scenarios where the sender doesn’t need to see their own message in the broadcast, such as a multiplayer game in which actions need to be shared with other players but not echoed back to the one performing the action.
Both methods have specific use cases and can be implemented easily with tools like Bun, allowing developers to handle broadcasting efficiently with minimal code.
This article delves into how to set up WebSocket broadcasting using Bun and demonstrates both broadcasting approaches, helping you build robust real-time applications.
In the first article of this series, WebSocket with JavaScript and Bun, we explored the structure of a WebSocket server that responds to messages sent by a client.
This article will explore channel subscriptions, a mechanism that enables broadcasting messages to multiple clients.
We’ll begin by presenting the complete code and then break it down to explore all the relevant parts in detail.
Create the broadcast.ts file:
console.log("? Hello via Bun! ?"); const server = Bun.serve({ port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000 fetch(req, server) { const url = new URL(req.url); if (url.pathname === "/") return new Response(Bun.file("./index.html")); if (url.pathname === "/surprise") return new Response("?"); if (url.pathname === "/chat") { if (server.upgrade(req)) { return; // do not return a Response } return new Response("Upgrade failed", { status: 400 }); } return new Response("404!"); }, websocket: { message(ws, message) { console.log("✉️ A new Websocket Message is received: " + message); ws.send("✉️ I received a message from you: " + message); ws.publish( "the-group-chat", `? Message from ${ws.remoteAddress}: ${message}`, ); }, // a message is received open(ws) { console.log("? A new Websocket Connection"); ws.subscribe("the-group-chat"); ws.send("? Welcome baby"); ws.publish("the-group-chat", "? A new friend is joining the Party"); }, // a socket is opened close(ws, code, message) { console.log("⏹️ A Websocket Connection is CLOSED"); const msg = `A Friend has left the chat`; ws.unsubscribe("the-group-chat"); ws.publish("the-group-chat", msg); }, // a socket is closed drain(ws) { console.log("DRAIN EVENT"); }, // the socket is ready to receive more data }, }); console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`); setInterval(() => { const msg = "Hello from the Server, this is a periodic message!"; server.publish("the-group-chat", msg); console.log(`Message sent to "the-group-chat": ${msg}`); }, 5000); // 5000 ms = 5 seconds
you can run it via:
bun run broadcast.ts
This code introduces broadcasting, allowing the server to send messages to all subscribed clients in a specific channel. It also differentiates between broadcasting to all clients (including the sender) or excluding the sender. Here's a detailed explanation:
const server = Bun.serve({ port: 8080, ... });
The initialization is the same of the previous article.
The server listens on port 8080 and similar to the previous example, it handles HTTP requests and upgrades WebSocket connections for /chat.
Broadcasting allows a message to be sent to all clients subscribed to a specific channel, like a group chat.
Here’s how the code achieves this:
open(ws) { console.log("? A new Websocket Connection"); ws.subscribe("the-group-chat"); ws.send("? Welcome baby"); ws.publish("the-group-chat", "? A new friend is joining the Party"); }
message(ws, message) { console.log("✉️ A new Websocket Message is received: " + message); ws.send("✉️ I received a message from you: " + message); ws.publish("the-group-chat", `? Message from ${ws.remoteAddress}: ${message}`); }
When a message is received from a client:
Note: The sender doesn't receive the broadcast message because we call the publish method on the ws object. You should use the server object to include the sender.
close(ws, code, message) { console.log("⏹️ A Websocket Connection is CLOSED"); const msg = `A Friend has left the chat`; ws.unsubscribe("the-group-chat"); ws.publish("the-group-chat", msg); }
When a client disconnects:
console.log("? Hello via Bun! ?"); const server = Bun.serve({ port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000 fetch(req, server) { const url = new URL(req.url); if (url.pathname === "/") return new Response(Bun.file("./index.html")); if (url.pathname === "/surprise") return new Response("?"); if (url.pathname === "/chat") { if (server.upgrade(req)) { return; // do not return a Response } return new Response("Upgrade failed", { status: 400 }); } return new Response("404!"); }, websocket: { message(ws, message) { console.log("✉️ A new Websocket Message is received: " + message); ws.send("✉️ I received a message from you: " + message); ws.publish( "the-group-chat", `? Message from ${ws.remoteAddress}: ${message}`, ); }, // a message is received open(ws) { console.log("? A new Websocket Connection"); ws.subscribe("the-group-chat"); ws.send("? Welcome baby"); ws.publish("the-group-chat", "? A new friend is joining the Party"); }, // a socket is opened close(ws, code, message) { console.log("⏹️ A Websocket Connection is CLOSED"); const msg = `A Friend has left the chat`; ws.unsubscribe("the-group-chat"); ws.publish("the-group-chat", msg); }, // a socket is closed drain(ws) { console.log("DRAIN EVENT"); }, // the socket is ready to receive more data }, }); console.log(`? Server (HTTP and WebSocket) is launched ${server.url.origin}`); setInterval(() => { const msg = "Hello from the Server, this is a periodic message!"; server.publish("the-group-chat", msg); console.log(`Message sent to "the-group-chat": ${msg}`); }, 5000); // 5000 ms = 5 seconds
Every 5 seconds, the server broadcasts a message to all clients in the "the-group-chat" channel using server.publish(...). Here we are using the server object.
WebSockets are a powerful tool for building real-time, interactive web applications. Unlike traditional HTTP communication, WebSockets provide a persistent, two-way channel that enables instant message exchange between the server and connected clients. This makes them ideal for scenarios like live chats, collaborative tools, gaming, or any application where low-latency communication is crucial.
In this article (and in the series), we explored the basics of setting up a WebSocket server using Bun, handling client connections, and broadcasting messages to subscribed clients. We also demonstrated how to implement a simple group chat system where clients can join a channel, send messages, and receive updates from both other clients and the server itself.
By leveraging Bun’s built-in WebSocket support and features like subscribe, publish, and unsubscribe, it becomes remarkably easy to manage real-time communication. Whether you’re sending periodic updates, broadcasting to all clients, or managing specific channels, WebSockets provide an efficient and scalable way to handle such requirements.
The above is the detailed content of WebSocket broadcasting with JavaScript and Bun. For more information, please follow other related articles on the PHP Chinese website!