WebSocket broadcasting with JavaScript and Bun
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.
Why Broadcasting Is Important
Broadcasting is essential for scenarios where multiple users need to stay synchronized or informed about the same updates in real-time. For example:
- Group chat applications: sending a message to all participants in a chat room.
- Collaborative tools: updating all users about shared documents or content changes.
- Live notifications: broadcasting breaking news, stock updates, or sports scores to multiple subscribers.
- Online gaming: synchronizing game states or actions across multiple players.
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.
Two approaches to broadcasting
When implementing broadcasting, there are two common strategies to consider:
- Broadcasting to all clients (including the sender)
- Broadcasting to all clients except the sender
Broadcasting to all clients (including the sender)
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.
Broadcasting to all clients except the sender
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.
The code for broadcasting with WebSockets
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:
Initializing the server
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 in WebSockets
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:
Subscribing to a channel (in the open Event)
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"); }
- ws.subscribe(channel): subscribes the client to the channel the-group-chat. All clients in this channel can now receive messages broadcasted to it.
- ws.send(...): the client is welcomed individually .
- ws.publish(channel, message): broadcasts a message to all clients in the channel.
Broadcasting messages (replying/broadcasting a message from a client in the message event)
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:
- The sender gets an acknowledgment via ws.send(...).
- The message is broadcasted to all clients (excluding the sender) in "the-group-chat" using ws.publish(...).
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.
Unsubscribing and broadcasting on disconnect (in the close event)
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:
- ws.unsubscribe(channel): removes the client from the channel subscription.
- A message is broadcasted to all remaining clients in the channel, notifying them of the disconnection.
Periodic server messages to all the clients
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.
Key methods
- ws.subscribe(channel): subscribes the current WebSocket client to a channel for group communication.
- ws.publish(channel, message): broadcasts a message to all clients in the specified channel (excluding the sender).
- server.publish(channel, message): similar to ws.publish, but used at the server level for broadcasting to all the subscribed clients (including the sender).
- ws.unsubscribe(channel): removes the current client from the channel.
Example flow
- A client connects to /chat, subscribing to "the-group-chat".
- The client sends a message to the server:
- The message is echoed back to the sender.
- The server broadcasts the message to all other clients in the channel.
- When a client disconnects:
- it is unsubscribed from the channel.
- The server notifies the remaining clients about the disconnection.
- Every 5 seconds, the server sends a periodic broadcast message to all clients.
Conclusion
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!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Detailed explanation of JavaScript string replacement method and FAQ This article will explore two ways to replace string characters in JavaScript: internal JavaScript code and internal HTML for web pages. Replace string inside JavaScript code The most direct way is to use the replace() method: str = str.replace("find","replace"); This method replaces only the first match. To replace all matches, use a regular expression and add the global flag g: str = str.replace(/fi

Article discusses creating, publishing, and maintaining JavaScript libraries, focusing on planning, development, testing, documentation, and promotion strategies.

The article discusses strategies for optimizing JavaScript performance in browsers, focusing on reducing execution time and minimizing impact on page load speed.

The article discusses effective JavaScript debugging using browser developer tools, focusing on setting breakpoints, using the console, and analyzing performance.

This article outlines ten simple steps to significantly boost your script's performance. These techniques are straightforward and applicable to all skill levels. Stay Updated: Utilize a package manager like NPM with a bundler such as Vite to ensure

This article will guide you to create a simple picture carousel using the jQuery library. We will use the bxSlider library, which is built on jQuery and provides many configuration options to set up the carousel. Nowadays, picture carousel has become a must-have feature on the website - one picture is better than a thousand words! After deciding to use the picture carousel, the next question is how to create it. First, you need to collect high-quality, high-resolution pictures. Next, you need to create a picture carousel using HTML and some JavaScript code. There are many libraries on the web that can help you create carousels in different ways. We will use the open source bxSlider library. The bxSlider library supports responsive design, so the carousel built with this library can be adapted to any

The article explains how to use source maps to debug minified JavaScript by mapping it back to the original code. It discusses enabling source maps, setting breakpoints, and using tools like Chrome DevTools and Webpack.

Sequelize is a promise-based Node.js ORM. It can be used with PostgreSQL, MySQL, MariaDB, SQLite, and MSSQL. In this tutorial, we will be implementing authentication for users of a web app. And we will use Passport, the popular authentication middlew
