客戶端如何及時收到服務端消息?本文系統梳理五大技術路線:輪詢 → 長輪詢 → SSE → WebSocket → 移動端專用長連接 (MQTT/APNs/FCM),對比原理、優缺點、適用場景,並深入剖析 Android/iOS 系統級長連接架構差異。
| 技術 | 原理 | 連接模式 | 服務端推送 | 客戶端複雜度 | 適用場景 |
|---|---|---|---|---|---|
| 短輪詢 | 定時發請求詢問 | 短連接 | 響應中返回 | 低 | 低實時、簡單業務 |
| 長輪詢 | 請求掛起直到有數據 | 長連接 | 響應中返回 | 中 | 中實時、兼容性好 |
| SSE | 單向流式響應 | 長連接 | 流式寫入 | 低 (原生 API) | 服務端→客戶端推送 |
| WebSocket | 全雙工協議 | 長連接 (ws://) | 雙向幀 | 中 | 雙向交互、IM、遊戲 |
| 移動端長連接 | 系統級 TCP 保活 | 持久 TCP | 推送通道 | 低 (SDK) | 移動端離線推送 |
客戶端發起 HTTP 長連接請求
↓
服務端接收請求,不立即響應,hold 住連接(非阻塞,不佔用線程)
↓
服務端有新數據 → 寫入響應流 → 客戶端收到
↓
客戶端處理數據 → 發起新長連接(或 SSE 自動復用)
| 維度 | 客戶端 | 服務端 |
|---|---|---|
| 同步/異步 | 異步發起請求,不阻塞主線程 | 異步處理業務,不阻塞 I/O 線程 |
| 阻塞/非阻塞 | 非阻塞等待響應 | 非阻塞 hold 連接,可同時處理其他請求 |
| 組合 | 異步非阻塞 | 異步非阻塞 (NIO/Netty/servlet async) |
| 特性 | 說明 |
|---|---|
| 協議層級 | 基於 TCP/IP,極輕量(固定頭 2 字節) |
| 模式 | 發布/訂閱,解耦發送方與接收方 |
| QoS | 0/1/2 三級質量保證 |
| 心跳 | Keep Alive 機制,客戶端發 PINGREQ,服務端回 PINGRESP |
| 遺囑 | Last Will Testament,異常斷線自動發布離線消息 |
| 適用性 | 低帶寬、不穩定網絡、嵌入式設備、移動端 |
Facebook Messenger、微信早期均採用 MQTT 或類似私有協議。
// 客戶端邏輯
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(() -> {
if (socket.isConnected()) {
sendHeartbeat(); // 發送 PING
startHeartbeatTimeoutTimer(); // 啟動超時定時器
}
}, 0, HEARTBEAT_INTERVAL, TimeUnit.SECONDS);
// 收到 PONG 取消超時定時器
// 超時未收到 → 判定斷開 → 重連邏輯(指數退避)
App Server → (HTTPS/HTTP/2 + JWT Token) → APNs Server
↓
系統級長連接 (device token 路由)
↓
iOS 設備 → 系統處理 → 展示通知 / 唤醒 App
為解決「N 個 App = N 條長連接」耗電痛點,華為/小米/OPPO/vivo/魅族/華碩等廠商聯合推出 統一推送聯盟:
需要雙向實時交互? → WebSocket
只需服務端→客戶端推送? → SSE (Web) / APNs/FCM/統一推送 (移動端)
移動端 App 必須離線收推送? → 集成廠商推送 SDK + 兜底自建長連接 (MQTT)
物聯網/嵌入式/弱網環境? → MQTT
簡單低實時/兼容舊瀏覽器? → 長輪詢
極簡輪詢/無長連接權限? → 短輪詢
理解底層協議差異、系統級長連接架構、心跳保活機制,能讓你在架構選型、性能調優、故障排查中游刃有餘。