---
# System prepended metadata

title: "【教學】\U0001F680 SSE、WebSocket與Polling大PK！實時長連接通訊技術萌新指南 ✨！"
tags: [跨平台APP開發, SSE, SocketIO, Web Development, Vue3, websocket, 前端開發, APP開發, polling, VueJS]

---

---
title: '【教學】🚀 SSE、WebSocket與Polling大PK！實時長連接通訊技術萌新指南 ✨！'
disqus: hackmd
---
# 【教學】🚀 SSE、WebSocket與Polling大PK！實時長連接通訊技術萌新指南 ✨！


![sse](https://hackmd.io/_uploads/H1nZSmEhxe.png)


## 🌟 摘要
嘿！想知道怎麼讓你的網站像聊天室一樣即時更新嗎？🤔

本篇文章要來解密三種實時通訊技術：
* **Server-Sent Events (SSE)**
* **WebSocket**
* **Polling**

我們會用最白話的方式告訴你它們到底在幹嘛、什麼時候該用哪一個，還有維護起來會不會讓你想哭 😭😭😭


## 💡 引言
現在的WEB APP都可能遇到要求「即時」更新的功能。
⚡⚡新訊息要馬上彈出來、股價、幣種行情要即時跳動、聊天室訊息要秒出現！但是要怎麼選擇合適的技術來實現這些需求呢？

其實這大段時間，提起這種技術，很多人都會陷入困惑：
- 「WebSocket 我知道有這東西，聽起來很厲害，但好像很複雜？」🤯
- 「Polling 實作很簡單，但會不會太耗資源？」😰
- 「SSE 是什麼？聽都沒聽過！」🙃

**好啦，開始劃重點！** 📝 

很多人都誤會 SSE 和 WebSocket 一樣複雜，但其實 SSE 根本就省事太多了！它基於標準 HTTP，瀏覽器還內建重連功能！


---


## 🏆 學術界都說讚！權威研究報告出爐

在開始之前，先給大家看個超厲害的研究報告！📊

**瑞典布萊金理工學院** 的學者們做了一個超詳細的性能測試（沒錯，就是那種很嚴肅的學術研究 🤓），他們比較了這幾種技術的真實表現：

🔗 研究報告：
[《Performance comparison of XHR polling, Long polling, Server sent events and Websockets》](https://www.diva-portal.org/smash/get/diva2:1133465/FULLTEXT01.pdf)

- **TCP連接數據** (第26頁)：XHR會導致連接數激增(高達289個連接)，而其他技術保持在100個連接
- **研究結論** (第42-43頁)
- **性能測試結果** (第24-37頁)

### 📈 驚人的發現：
- **TCP連接大爆炸** 💥：傳統的XHR Polling 會產生高達 **289個連接**！而其他技術只需要100個左右
- **效能冠軍揭曉** 🥇：報告第43頁直接下結論：

> 💬 "Websockets and Server sent events were measured to be the highest performing of the studied technologies."
> 

翻譯：WebSocket 和 SSE 就是本次比較雙冠王！🎉

### 性能比較表

| 技術 | 延遲 | 頻寬使用 | CPU使用 | 服務器負載 | 成本與擴展性 |
|------|------|----------|----------|------------|--------------|
| **HTTP Polling** | 高（受輪詢間隔限制） | 最高（每次完整HTTP請求） | 中 | 高（大量TCP連接） | 差（高併發連接爆炸） |
| **SSE** | 低（即時推送） | 低（僅傳輸新資料） | 低 | 中（單向長連接） | 佳（標準HTTP） |
| **WebSocket** | 最低（全雙工） | 最低（最小幀開銷） | 低 | 中（需維護連接） | 中（需特殊配置） |



## 🔄 HTTP Polling：老派但實用的笨方法

### 🤔 什麼是 Polling？
就是最簡單粗暴的方法啦！想像他是個很黏人的小小孩，每隔5秒就問媽媽「有新訊息嗎？有新訊息嗎？有新訊息嗎？」🥺

你的網頁就是那個小鬼，Server 就是覺得他很吵卻又一臉無奈的馬麻... 😅

### ⚙️ 怎麼實作？
超級簡單！用我們熟悉的工具就行：
- 拿出你的 `fetch()` 或 `Axios` 📞
- 設個定時器 `setInterval()` ⏰
- 每隔幾秒戳一下伺服器：「欸欸欸，有更新嗎？」

### 🔍 底層到底發生了什麼？
每次問問題的時候：
- 🤝 建立全新的 TCP 連線（握手）
- 📤 送出完整的 HTTP 請求
- 📥 接收回應
- 👋 關閉連線（掰掰）
- ⏱️ 等個幾秒...然後重複循環！

### 然後... 😰 問題來了...
如果你的瀏覽器有30個分頁同時開著，每個都在問「有更新嗎？」，伺服器就會：
- **崩潰邊緣** 💥：連線數量爆炸增長
- **荷包大失血** 💸：每次後端都要處理完整的 HTTP 請求

這其實和💥**DDoS**💥是差不多的行為，拜託一定要慎用！

但如果你的資料更新頻率超低（比如每5~10分鐘才更新一次天氣），那 Polling 其實還OK啦～ 🌤️

---

## 📡 SSE：簡單容易上手！建置成本最低的長連接！

### 💖 為什麼選 SSE？

- **HTTP 就是王道** 👑：不需要特殊伺服器，現有的就能用
- **一條連線走天下** 🛣️：建立一次連線就能一直用
- **瀏覽器是暖男** 🥰：自動幫你處理重連，不用自己寫Message Queue
- **最現代的解決方案** 🚀：使用HTML 5專門的 `EventSource` API，可穿透大多數代理和防火牆


### 🛠️ 怎麼用 SSE？
瀏覽器內建就有：

```javascript
// 就這麼簡單！🎉
const eventSource = new EventSource('/api/sse?token=your-token');

eventSource.onmessage = function(event) {
  console.log('收到新訊息啦！', event.data);
  // 在這裡更新你的 UI ✨
};

// 自動重連？瀏覽器幫你搞定！😎
```

不過要特別注意喔，根據瀏覽器相容支援表來看
目前比較新版本的 Android Chrome才有支援，iOS Safari則沒問題！
![image](https://hackmd.io/_uploads/B1Dm6M4nle.png)


### 🔧 實作細節大揭密
- **單向溝通** 📤：只有伺服器可以推送給你（但通常這就夠了）
- **文字格式** 📝：傳輸純文字資料，通常是 JSON
- **Token 問題** 🎫：Header 放不了 token，要用 query string 或 cookie
- **自動重連** 🔄：斷線了？瀏覽器自動幫你重連！
- **需心跳檢測** 💖：每秒後端最好都傳個ping訊息防止斷開！
- **事件 ID** 🆔：有 `Last-Event-ID` 機制，重連後只拿新訊息
- **輕微延遲** ⏱️：走 HTTP chunked 傳輸，比 WebSocket 慢個1-100ms（但感覺不出來啦～）

### 🎯 最適合的場景
- **通知系統** 🔔：新訊息、系統警告（1-100ms 延遲完全不影響）
- **即時儀表板** 📊：股價、監控數據（人眼根本感覺不出來，除非真的要精準）
- **後台管理系統** 🖥️：各組運營資料更新（單向推送就夠了）
- **直播數據** 📺：觀看人數、彈幕統計（不需要毫秒級準確）

---


## 🔌 WebSocket：雙向溝通霸權

### 🚀 WebSocket 的超能力

- **全雙工通訊** ⚽：客戶端和伺服器都能隨時發消息
- **速度超快** ⚡：建立連線後，開銷超級小
- **支援二進位** 🔢：不只文字，圖片、檔案都能傳
- **協議升級** 🎭：從 HTTP 搖身變成 WebSocket

### 🛠️ 怎麼使用？
```javascript
// 建立 WebSocket 連線
const ws = new WebSocket('wss://your-server.com/socket');

ws.onopen = function() {
  console.log('連線成功！可以開始聊天了 🎉');
  ws.send('Hello Server! 👋');
};

ws.onmessage = function(event) {
  console.log('收到回覆：', event.data);
};

ws.onclose = function() {
  console.log('連線斷了...要重連嗎？ 😥');
  // 原生的websocket這裡要自己寫重連邏輯... 😅
};
```

### 但是...麻煩事也不少
**伺服器要特殊設定** 🔧：
- 需要支援 WebSocket 協議的伺服器
- 可能需要額外的服務或模組
- 負載均衡器也要特殊處理

**自己動手做** 🔨：
- 重連邏輯要自己寫
- 心跳檢測要自己處理
- 連線狀態要自己管理

**但是！有個超級英雄拯救了一切！**


![image](https://hackmd.io/_uploads/rJbyJQV2lx.png)


### 🌟 Socket.IO 的魔法功能：
- **自動重連** 🔄：斷線了？自動重連！不用你操心！
- **心跳包** 💓：自動幫你維持連線活躍
- **降級處理** 🎭：WebSocket 不行？自動降級到 Long Polling！
- **房間系統** 🏠：輕鬆實現群組聊天、分頻道推送
- **事件驅動** ⚡：用 `emit` 和 `on` 就能輕鬆溝通
- **跨平台** 🌍：瀏覽器、Node.js、手機 App 都支援

### 💻 Socket.IO 使用範例：
```javascript
// 客戶端 - 超級簡單！
import io from 'socket.io-client';

const socket = io('http://localhost:3000');

// 發送訊息
socket.emit('chat message', 'Hello World! 👋');

// 接收訊息
socket.on('chat message', (msg) => {
  console.log('收到訊息：', msg);
});

// 加入房間
socket.emit('join room', 'room1');

// 連線狀態處理（自動處理，但你也可以監聽）
socket.on('connect', () => console.log('連線成功！🎉'));
socket.on('disconnect', () => console.log('斷線了，但會自動重連 😌'));
```


```javascript
// 伺服器端 - Node.js
const io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log('用戶連線了！🎉');

  // 處理聊天訊息
  socket.on('chat message', (msg) => {
    // 廣播給所有人
    io.emit('chat message', msg);

    // 或者只發給特定房間
    // socket.to('room1').emit('chat message', msg);
  });

  // 處理房間加入
  socket.on('join room', (room) => {
    socket.join(room);
    socket.to(room).emit('user joined', 'OOO加入了聊天！');
  });
});
```

### 🎯 為什麼 Socket.IO 這麼受歡迎？
- **開發速度快** ⚡：複雜功能幾行代碼搞定，MVP能快速落地
- **穩定性強** 🛡️：自動處理各種邊緣情況
- **功能豐富** 🎁：房間、namespace、middleware都有
- **社群強大** 👥：文檔完整、範例超多
- **生產就緒** 🏭：大公司都在用，經過實戰考驗

所以說，雖然原生 WebSocket 有些麻煩，但有了 Socket.IO，WebSocket 開發變得超級愉快！🎊

:::info
但別忘了這套東西可是前後端都要同時使用哦！
Java Spring Boot、Golang、Rust都有對應的版本可以使用！
而前端大多時候就只要選Latest就行啦~
:::

**網路環境挑剔** 🌐：
- 有些代理或防火牆會擋 WebSocket
- 企業網路環境可能有限制

### 🎯 最適合的場景
- **即時通訊** 💬：Messenger、Discord（需要雙向+超低延遲）
- **多人遊戲** 🎮：需要毫秒級反應的即時互動
- **協同編輯** ✏️：Google Docs、Figma（多人同步編輯）
- **即時交易** 📈：高頻交易系統（每毫秒都是錢！）

## 技術選擇指南

### 📊 實時通訊技術選擇決策樹

```
Q1: 需要雙向通訊嗎？（客戶端是否需要頻繁向服務發送消息？）
├── ✅ 是 → Q2
└── ❌ 否 → Q3

Q2: 是否需要極低的延遲和大量消息交換？
├── ✅ 是 → 🔌 推薦使用 WebSocket
└── ❌ 否 → Q3

Q3: 環境是否涉及多個分頁同時打開？
├── ✅ 是 → Q4
└── ❌ 否 → Q5

Q4: 是否關注資源效率和簡化的維護？
├── ✅ 是 → 📡+ 推薦使用 SSE + SharedWorker
└── ❌ 否 → Q5

Q5: 是否需要即時更新？（秒級或分鐘級響應）
├── ✅ 是 → 📡 推薦使用 SSE
└── ❌ 否 → 🔄 使用簡單的 Polling 即可
```

### 🔄 適合使用Polling的場景
- 數據更新頻率和粒度都極低（如每五分鐘至十分鐘以上才更新）
- 簡單實踐優先於效能，但通常成本不一定是最低，特別是瀏覽器記憶體比較危險
- 不需要即時性
- 後端架構難以支持長連接

### 📡 適合使用SSE的場景
- 服務到客戶端的單向通訊需求
- 需要即時通知或更新，且須採成本最低路線
- 希望利用標準HTTP基礎設施
- 不考慮手機版 (Safari iOS和火狐可用但Chrome不行)
- **實務應用**：通知系統、實時數據儀表板、即時行情、天氣更新等

### 🤝 適合使用WebSocket的場景
- 雙向通訊需求（客戶端頻繁發送消息）
- 極低延遲要求
- 大量訊息交換
- 有考慮配置專門的WebSocket服務
- **實務應用**：聊天室、多人遊戲、協同編輯工具(Figma、社群共筆工具)等

---

## 🎯 總結

在選擇實時通訊技術時，每種方案都有其適用場景：

### 🔄 HTTP Polling
- **適用場景**：低頻更新、簡單實現優先
- **劣勢**：多分頁環境下連接數量激增（🔄×30）
- **維護成本**：低複雜度，但高服務器負載

### 📡 SSE (Server-Sent Events)
- **適用場景**：單向通知、實時儀表板、風險警報
- **優勢**：標準HTTP協議、瀏覽器原生重連、低維護成本
- **最佳實踐**：📡+ SSE結合SharedWorker實現多分頁共享單一連接

### 🔌 WebSocket
- **適用場景**：聊天室、雙向頻繁通訊、協同編輯
- **優勢**：全雙工通訊、低延遲、二進制支持
- **劣勢**：需專門服務器、手動重連邏輯、防火牆穿透挑戰

**對於運營後台這類多分頁環境，📡+ SSE結合SharedWorker提供了明顯的優勢**：

- ⬇️ **顯著減少服務器連接數**（從30降至1，減少97%）
- 🔔 **提供更一致、更可控的通知體驗**（主分頁控制聲音）
- 🚀 **避免多分頁環境中的資源競爭和重複工作**
- ⚡ **保持近乎實時的推送能力，無需複雜的WebSocket維護**

對於大多數通知、風控警報和數據更新場景，特別是在多分頁環境下，📡 **SSE提供了更優的性能/維護比**。當然，如果需要客戶端到服務的頻繁通訊，有條件的話則🔌 **WebSocket仍然是更佳選擇**。

---

## 參考來源

### Server-Sent Events (SSE)
- **MDN Web Docs - Server-Sent Events**：[Server-sent events - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
- **WHATWG 標準 - Server-Sent Events**：[HTML Standard](https://html.spec.whatwg.org/multipage/server-sent-events.html)
- **MDN Web Docs - EventSource API**：[EventSource - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)

### WebSocket
- **MDN Web Docs - WebSocket API**：[The WebSocket API (WebSockets) - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
- **WHATWG 標準 - WebSocket**：[WebSockets Standard](https://websockets.spec.whatwg.org/)

### SharedWorker
- **MDN Web Docs - SharedWorker**：[SharedWorker - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)
- **MDN Web Docs - 使用 Web Workers**：[Using Web Workers - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
---

###### tags: `VueJS` `Vue3` `websocket` `SSE` `polling` `SocketIO` `APP開發` `跨平台APP開發` `前端開發` `Web Development`
