SpringBoot 接入SSE實現消息實時推送的優點,原理以及實現
前言
上一篇文章 我寫的關于SpringBoot整合t-io是websocket實時通信的文章中我們可以了解到 websocket是雙向通信的,而且需要TCP連接的支持,今天在這里我要說的SSE(Server-Sent Events) 是一個單項通信的消息實時推送框架,它僅支持由服務器發送消息到客戶端,而且是基于HTTP/HTTPS的。對于我們只需要從服務器向客戶端推送的數據使用SSE會更加輕便,性能更強。
SSE 單向數據推送的優點
1. 簡單易用
- 基于HTTP:SSE使用標準的HTTP協議,無需額外的協議升級(如WebSocket的握手)。這使得它更容易集成到現有HTTP基礎設施中。
- 客戶端API簡單:瀏覽器端使用
EventSource
對象,API非常簡單,只需幾行代碼即可建立連接并監聽事件。 - 自動重連:
EventSource
內置了自動重連機制,當連接斷開時,客戶端會自動嘗試重新連接。
2. 單向通信(服務器到客戶端)
- 對于只需要服務器向客戶端推送數據的場景(如實時通知、股票行情、新聞更新等),SSE是理想的選擇。它不需要客戶端向服務器發送數據,從而減少了復雜性和開銷。
3. 輕量級
- SSE的數據格式是純文本,每條消息由
event
、data
和id
等字段組成,結構簡單,解析高效。 - 與WebSocket相比,SSE在協議層更輕量,不需要維護雙向通信的復雜狀態。
4. 支持標準HTTP功能
- 安全性:SSE可以通過HTTPS運行,確保數據傳輸的安全性。
- 認證和授權:由于基于HTTP,可以方便地使用Cookie、HTTP認證或Token進行訪問控制。
- 代理友好:SSE可以通過標準的HTTP代理和防火墻,而WebSocket可能會在某些嚴格的網絡環境中被阻止。
5. 自動處理連接管理
- 客戶端(瀏覽器)的
EventSource
會自動處理連接建立、斷開和重試邏輯,開發者無需手動實現這些功能。
6. 文本數據友好
- 對于推送文本數據(如JSON、XML、純文本),SSE非常高效。如果需要傳輸二進制數據,則WebSocket更合適。
7. 兼容性
- 瀏覽器支持:現代瀏覽器(包括IE/Edge、Firefox、Chrome、Safari、Opera)都支持SSE。對于不支持的瀏覽器(如IE11及以下),可以使用polyfill(如
eventsource
庫)。 - 服務器端:幾乎所有后端語言和框架都支持SSE,因為本質上它只是長輪詢的標準化和簡化。
8. 效率
- 相比傳統的輪詢(Polling)或長輪詢(Long Polling),SSE使用持久連接,服務器可以在有數據時立即推送,減少了不必要的請求和延遲。
9. 事件驅動
- 服務器可以發送不同類型的事件(通過
event
字段),客戶端可以為不同的事件注冊不同的處理函數,實現更靈活的消息處理。
10. 與現有技術棧集成容易
- 如果你已經有一個RESTful API,添加SSE端點通常很簡單,無需引入額外的庫或中間件(如WebSocket服務器)。
對比WebSocket
- 雙向 vs 單向:WebSocket提供全雙工通信,適合需要雙向交互的場景(如聊天應用)。SSE僅支持服務器到客戶端的單向通信。
- 復雜性:WebSocket需要更復雜的服務器和客戶端實現,而SSE更簡單。
- 二進制數據:WebSocket支持二進制數據,SSE僅支持文本(但可以Base64編碼二進制數據)。
適用場景
- 實時通知(如郵件、消息提醒)
- 實時數據監控(如股票行情、實時日志)
- 新聞推送、賽事比分更新
- 任何需要服務器主動向客戶端推送數據的場景
SSE 代碼實現
1. SSE 工具類,支持消息推送與心跳保持
@Slf4j
public class SseUtils {// 存儲用戶ID與SseEmitter的映射private static final Map<Long, SseEmitter> emitterMap = Maps.newConcurrentMap();// 心跳任務映射:用戶ID -> 心跳任務pri