廣播是 WebSocket 最強大的功能之一,它允許伺服器同時向多個連接的客戶端發送訊息。與在單一客戶端和伺服器之間交換訊息的點對點通訊不同,廣播使單一訊息能夠到達一組客戶端。這使得它對於即時、協作和互動式應用程式不可或缺。
廣播對於多個使用者需要保持同步或即時了解相同更新的場景至關重要。例如:
在這種情況下,廣播可確保所有連接的使用者保持同步,而無需為每個客戶端進行單獨的伺服器調用,否則效率低且容易出現延遲。
實施廣播時,有兩種常見策略需要考慮:
此方法將訊息傳送到連接到特定通道的所有客戶端,包括發起訊息的客戶端。
此方法適用於每個客戶端(包括發送者)都需要接收廣播的情況,例如在群組聊天中顯示訊息的確認或更新。
在這種情況下,訊息將廣播給除發送者之外的所有用戶端。
這種方法非常適合發送者不需要在廣播中看到自己的訊息的場景,例如多人遊戲,其中的操作需要與其他玩家共享,但不需要回顯給執行該操作的玩家.
這兩種方法都有特定的用例,並且可以使用 Bun 等工具輕鬆實現,從而使開發人員能夠以最少的程式碼高效地處理廣播。
本文深入探討如何使用 Bun 設定 WebSocket 廣播,並示範了兩種廣播方法,幫助您建立強大的即時應用程式。
在本系列的第一篇文章《使用 JavaScript 和 Bun 的 WebSocket》中,我們探討了回應客戶端發送的訊息的 WebSocket 伺服器的結構。
本文將探討頻道訂閱,這是一種能夠向多個客戶端廣播訊息的機制。
我們將首先展示完整的程式碼,然後將其分解以詳細探索所有相關部分。
建立broadcast.ts檔:
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
您可以透過以下方式運行它:
bun run broadcast.ts
這段程式碼引入了廣播,允許伺服器向特定頻道中的所有訂閱客戶端發送訊息。它還區分向所有客戶端(包括發送者)廣播或排除發送者。詳細解釋如下:
const server = Bun.serve({ port: 8080, ... });
初始化與上一篇相同。
伺服器偵聽連接埠 8080,與前面的範例類似,它處理 HTTP 請求並升級 /chat 的 WebSocket 連線。
廣播允許將訊息傳送給訂閱特定頻道的所有客戶端,例如群組聊天。
以下是程式碼如何實現這一點:
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}`); }
收到來自客戶端的訊息時:
注意:發送者沒有收到廣播訊息,因為我們呼叫了 ws 物件的publish 方法。您應該使用伺服器物件來包含寄件者。
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); }
當客戶端斷開連線時:
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
每 5 秒,伺服器使用 server.publish(...) 向「the-group-chat」頻道中的所有用戶端廣播訊息。這裡我們使用伺服器對象。
WebSockets 是建立即時、互動式 Web 應用程式的強大工具。與傳統的 HTTP 通訊不同,WebSocket 提供持久的雙向通道,支援伺服器和連線的用戶端之間的即時訊息交換。這使得它們非常適合即時聊天、協作工具、遊戲或任何低延遲通訊至關重要的應用程式。
在本文(以及本系列)中,我們探索了使用 Bun 設定 WebSocket 伺服器、處理客戶端連線以及向訂閱客戶端廣播訊息的基礎知識。我們也示範如何實作一個簡單的群組聊天系統,用戶端可以加入頻道、傳送訊息以及從其他用戶端和伺服器本身接收更新。
透過利用 Bun 內建的 WebSocket 支援和訂閱、發布和取消訂閱等功能,管理即時通訊變得非常容易。無論您是發送定期更新、向所有用戶端廣播還是管理特定通道,WebSocket 都提供了一種高效且可擴展的方式來處理此類需求。
以上是使用 JavaScript 和 Bun 進行 WebSocket 廣播的詳細內容。更多資訊請關注PHP中文網其他相關文章!