什麼是網頁即時通訊技術?
網頁即時通訊技術 (Real-time Web Communication) 是指一組允許伺服器與客戶端之間實現「低延遲資料同步」的技術方案。其演進從傳統透過 AJAX 模擬的 Long-Polling (長輪詢),發展到單向推送的 SSE (Server Sent Events),以及現代主流的 WebSocket (全雙工通訊)。這類技術打破了「由客戶端主動請求」的傳統模式,讓伺服器能主動將最新訊息(如聊天訊息、即時股價或 IoT 狀態)推送給用戶。選擇合適的即時通訊技術是提升網頁互動性、構建響應式應用程式的核心關鍵。
在另外一篇文章小編介紹了怎麼透過 非同步 AJAX 的方式 跟伺服器進行溝通,那需要即時的同步溝通怎麼辦?本篇 網頁即時通訊技術 指南將帶您深入了解現代網頁如何實現高效的資料同步。
這篇文章接著會介紹可以做到 網頁即時通訊 服務的主流技術:
API 在系統設計上是為了溝通而產生的,而非同步溝通技術較為簡單且容易實作,即時通訊 則需要較多層面的情境與技術考量。
以男女之間來說,非同步的溝通比較容易造就產生時間管理大師,即時通訊則相對較為困難。
即時通訊原理:單工、半雙工與全雙工通訊
在 2010 年 Chrome 開始支援了新的即時通訊 API 後 Web App 開始走向全新的時代,即時通訊原理 從雙方通訊的方式可以分成下面三種:
- 單工:訊號只在一個方向上進行傳遞,像是寫情書給喜歡的女生。
- 雙工:允許雙向資料傳輸,像是曖昧期的相處。
- 半雙工:可切換方向的單工通訊,像是只有一方有意思的時候,訊息通常是單向的。
- 全雙工:現代 即時通訊,即將熱戀中的男女,雙方同時接收或是傳送訊息。
非同步溝通:屬於單工或半雙工,注重的會是資訊的 "傳入" 以及 "傳出"。
即時通訊:全雙工,注重的會是 "監聽事件" 以及 "發出事件"。
Long-Polling:運用 AJAX 模擬即時通訊的傳統方案
從翻譯來看就是比較長的 Polling,Long-Polling 的用途其實是以舊的 AJAX 技術模擬 即時通訊 的效果。
- Polling: 前端向後端發出請求,如果沒拿到想要的資料就重發,伺服器負載較重。
- Long-Polling:
- Client 發 Request 給 Server。
- Server 送 Response 給 Client 後才斷開連線 (降低伺服器負擔但占用連線數)。
- Client 收到後再發 Request 給 Server。
Polling 像是奪命連環 Call 會一直 Call 到有反應為止,就像正妹的 Line 打開永遠都是 999+ 未讀未接一樣,負擔其實很大。Long-Polling 會是優化版本的,正妹雖然有好幾個通訊軟體,雖然打 Line 過去後被 Mute (因為切去用 Messenger),但至少可以確定之後會回。
以下為之前我練習 Long-Polling 實作範例程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| let timeout;
function valueChanged(value) { return (dispatch) => { dispatch(loadSuggestionsInProgress()); dispatch({ type: "VALUE_CHANGED", payload: { value, }, });
timeout && clearTimeout(timeout);
timeout = setTimeout( () => { axios .get(`/suggestions?q=${value}`) .then((response) => dispatch(loadSuggestionsSuccess(response.data.suggestions)) ) .catch(() => dispatch(loadSuggestionsFailed())); }, 1000, value ); }; }
|
Server Sent Events (SSE):單向推送伺服器事件的實作
網頁一般來說是由客戶端向伺服器請求資料。藉由 Server Sent Events (SSE), 伺服器在任何時候都可以向客戶端推送資料,推送進來的訊息可以在客戶端上做事件與資料的處理。
像是現在 LLM 的聊天過程大多較適合用這種做法,一有部分結果時就逐步回傳給問問題的使用者,方便提早確認是否要繼續。
Server Sent Events 比較像是正妹找工具人的概念,工具人們都會等待正妹的指令,指令一下就會進行動作。
以下為之前我練習 Server Sent Events 實作 範例程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| let clients = []; const server = express();
function sendEventsToClients() { clients.forEach((c) => { c.res.write(`change`); }); }
async function modify(req, res) { res.json({ status: 1 }); return sendEventsToClients(); }
server.get("/modify", modify); server.get("/listen", (req, res) => { const { clientId } = req.query; const headers = { "Content-Type": "text/event-stream", Connection: "keep-alive", "Cache-Control": "no-cache", }; res.writeHead(200, headers); res.write(""); const newClient = { id: clientId, res, }; clients.push(newClient); req.on("close", () => { clients = clients.filter((c) => c.id !== clientId); }); });
const events = new EventSource("/listen?clientId=test"); events.onmessage = (event) => { if (event.data) console.log(event.data); };
events.addEventListener("ping", function (event) { if (event.data) console.log(event.data); });
|
WebSocket:實現低延遲、全雙工即時通訊的標準
WebSocket 這個 API 在不必 Polling 伺服器的情況下,讓用戶傳送訊息至伺服器並接受事件驅動回應,達到低延遲、全雙工的效果。接近真的談戀愛的溝通,雙方各自在沒什麼負擔的情況下進行訊息的交流。
Socket.IO 簡介:Event-Based 的通訊框架
Socket.IO 屬於 Node.js 解決方案,封裝了 Long-Polling 及 WebSocket,是一個 Event-based 全雙工的通訊函式庫。
當和 React 專案整合時,需要注意事件是否影響畫面渲染,避免每渲染一次就重新建立連結、重新監聽事件、重新發出訊息,記憶體很快就會用完,處理器來不及處理。
後端的基本範例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const express = require("express"); const app = express(); const http = require("http"); const server = http.createServer(app); const { Server } = require("socket.io"); const io = new Server(server);
app.get("/", (req, res) => { res.sendFile(__dirname + "/index.html"); });
io.on("connection", (socket) => { console.log("a user connected"); socket.on("message", (msg) => { console.log("message: " + msg); }); });
server.listen(3000, () => { console.log("listening on *:3000"); });
|
前端的基本範例:
1 2 3 4 5 6 7 8 9 10 11 12
| var socket = io();
var form = document.getElementById("form"); var input = document.getElementById("input");
form.addEventListener("submit", function (e) { e.preventDefault(); if (input.value) { socket.emit("message", input.value); input.value = ""; } });
|
MQTT:物聯網應用的輕量級通訊協定
MQTT (Message Queuing Telemetry Transport) 適合輕量級物聯網使用,封包較小可以支援大量的 Client。主要是以 TCP/IP 協定上去優化且取代 HTTP 這種較肥的資料傳輸協定,因此會需要一個訊息中介軟體 (MQTT Broker) 來提供解決方案。
底下官方範例會是使用官方提供的 MQTT Broker mqtt://test.mosquitto.org,若為自己的服務需要自行架設。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <html> <head> <title>test Ws mqtt.js</title> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> </head> <body> <script> const mqtt = require("mqtt"); const client = mqtt.connect("mqtt://test.mosquitto.org");
client.on("connect", function () { client.subscribe("presence", function (err) { if (!err) { client.publish("presence", "Hello mqtt"); } }); });
client.on("message", function (topic, message) { console.log(message.toString()); client.end(); }); </script> </body> </html>
|
FAQ:網頁即時通訊常見問題
Q1:WebSocket 與 HTTP 請求最大的差別是什麼?
A:HTTP 是「一問一答」且由客戶端發起的(Request-Response);而 WebSocket 是持久性的連結,一旦握手成功,伺服器與客戶端即可「隨時且雙向」發送訊息,不需要每次都重新傳送標頭 (Header) 資訊,大幅降低了 overhead。
Q2:什麼時候該選 SSE 而不是 WebSocket?
A:如果您的應用場景是「純單向推送」(例如:新聞跑馬燈、即時比分、系統監控面板),SSE 是更簡單且輕量的選擇。它基於標準 HTTP 協議,具備自動斷線重連機制,且對伺服器資源消耗較 WebSocket 低。只有在需要「高頻率雙向互動」(如:線上聊天室、共編文件)時,才推薦使用 WebSocket。
Q3:Socket.IO 與原生 WebSocket 有什麼不同?
A:Socket.IO 是一個高階封裝庫。它不僅支援 WebSocket,還內建了自動重連、房間分組 (Rooms)、以及在環境不支援 WebSocket 時自動降級 (Fallback) 為 Long-Polling 的功能。對於快速開發具備強韌性的即時應用,Socket.IO 能省去許多底層維護的麻煩。
更多相關文章
想徹底解決 CSS 命名衝突嗎?本篇 CSS in JS 指南深入探討在 React 應用中管理樣式的最佳實踐。我們將解析 styled-components、CSS Modules 與 Facebook 最新 StyleX 的優缺點。前 150 字直接回答 CSS in JS 定義,助您在提升模組化程度的同時做出最佳技術選型。
網頁該用 CSR 還是 SSR 渲染?本篇 React 網頁渲染模式指南深入解析兩者差異。我們將探討 SPA 的開發優勢、SSR 對 SEO 的重要性,以及如何透過 Next.js 解決渲染難題。前 150 字直接回答渲染模式定義,助您在提升網頁性能的同時做出正確的架構選型。
想提升 JavaScript 開發效率嗎?本篇指南深度解析前端開發者不可或缺的工具鏈。我們將探討 Linter 語法檢查、Babel 跨瀏覽器支援、npm 套件管理、Git 版本控制以及 CI/CD 自動化流程。前 150 字直接回答前端工具的核心價值,助您掌握現代網頁開發的工程化思維,打造高品質、易維護的軟體系統。
想掌握前端資料交換的核心嗎?本篇指南深度解析 AJAX 技術演進。我們將從傳統的 XMLHttpRequest 談起,探討現代 Fetch API 與 Axios 的實務應用,並解析 Promise 與 Async/Await 如何優化非同步程式碼。前 150 字直接回答 AJAX 核心定義,助您建立高效的前端通訊架構,優化網頁效能與使用者體驗。
想深入了解網頁是如何記住您的嗎?本篇指南深度解析 HTTP Cookies 的原理與實作。我們將探討 Cookie 在狀態管理中的角色,並分享 Express.js 的實戰配置。前 150 字直接回答 Cookie 核心定義,助您透過 HttpOnly 與 Secure 參數有效防範 XSS 攻擊,建構高品質且安全的網頁應用。
喜歡這篇文章,請幫忙拍拍手喔 🤣