SSE(Server-Sent Events)詳解
🧠 什么是 SSE?
SSE(Server-Sent Events) 是 HTML5 標準中定義的一種通信機制,它允許服務器主動將事件推送給客戶端(瀏覽器)。與傳統的 HTTP 請求-響應不同,SSE 是一種基于 HTTP 的單向流式通信協議 。
📌 核心特性
特性 描述 通信方式 單向:服務器 → 客戶端 連接類型 持久的 HTTP 長連接 數據格式 文本(MIME 類型:text/event-stream
) 自動重連 瀏覽器自動支持 底層協議 HTTP/1.1,兼容 HTTP 代理、緩存、身份驗證 建立方式 瀏覽器端使用 EventSource
對象
🧱 通信流程(架構圖)
瀏覽器(客戶端)
└── 發起 HTTP GET 請求(Accept: text/event-stream)↓
服務器端(保持連接)
└── 每當有事件,推送:data: xxxid: 1event: myEventretry: 3000[連接不斷,服務器持續發送,客戶端持續接收]
🧪 示例詳解
1. 客戶端(JS)
const source = new EventSource ( '/events' ) ; source. onmessage = ( event ) => { console. log ( '默認消息:' , event. data) ;
} ; source. addEventListener ( 'update' , ( event ) => { console. log ( '收到 update 事件:' , event. data) ;
} ) ; source. onerror = ( err ) => { console. error ( '連接異常' , err) ;
} ;
2. 服務器端(Node.js 示例)
app. get ( '/events' , ( req, res ) => { res. setHeader ( 'Content-Type' , 'text/event-stream' ) ; res. setHeader ( 'Cache-Control' , 'no-cache' ) ; res. setHeader ( 'Connection' , 'keep-alive' ) ; res. write ( 'retry: 5000\n' ) ; res. write ( 'event: update\n' ) ; res. write ( ` data: 你好,客戶端\n\n ` ) ; const interval = setInterval ( ( ) => { res. write ( ` data: 當前時間 ${ new Date ( ) . toISOString ( ) } \n\n ` ) ; } , 3000 ) ; req. on ( 'close' , ( ) => { clearInterval ( interval) ; res. end ( ) ; } ) ;
} ) ;
🎯 典型應用場景
場景 描述 實時通知系統 消息推送、任務進度提醒 實時監控面板 日志、CPU、內存、API 狀態 數據大屏 股票/氣象/新聞流更新 聊天室(只讀方) 只需服務器廣播消息 DevTools/日志監聽 構建日志實時顯示
📄 SSE 消息格式
event: update
id: 12345
retry: 5000
data: 你好
data: 世界
字段說明
字段 說明 data:
消息內容,可多行,客戶端拼接為一條 event:
事件名稱,配合 JS 的 addEventListener
使用 id:
消息 ID,客戶端會自動緩存用于斷線續傳 retry:
告訴瀏覽器下次重連時間(ms)
🧰 與 WebSocket 對比
對比項 SSE WebSocket 通信方向 單向(服務器 → 客戶端) 雙向 協議 基于 HTTP 使用 ws:// 或 wss://(非 HTTP) 使用復雜度 簡單(瀏覽器原生支持) 需要手動管理消息格式、連接狀態 數據格式 純文本(text/event-stream
) 文本或二進制 自動重連 瀏覽器原生支持 需要自行實現 代理支持 很好(HTTP 代理可用) 差(很多 HTTP 代理不支持) 應用場景 實時通知、日志流 聊天、游戲、協同操作等交互頻繁的場景
📡 瀏覽器支持情況
瀏覽器 支持情況 Chrome ? Firefox ? Safari ? Edge(Chromium) ? Internet Explorer ? 不支持 移動端瀏覽器 ?(多數現代瀏覽器)
?? 限制與注意事項
不支持 IE 只能從服務器推送 受限于 HTTP 連接數 不適合傳輸大量二進制數據
🔐 跨域 & 認證
Access-Control-Allow-Origin: *
Content-Type: text/event-stream
new EventSource ( ` /events?token=abc123 ` ) ;
📦 框架與工具支持
技術棧 支持方式 Node.js 原生、Express、NestJS Python Flask + flask-sse
,Django Channels Java Spring WebFlux、Servlet 推送 Go 原生 net/http
Rust Actix、Rocket 支持 SSE Vue/React 用 EventSource
封裝 Hook/Composables Nginx 可代理 SSE,需關閉緩存,配置 proxy_buffering off;
? 總結:SSE 的優勢與應用判斷
? 簡單、輕量級、易于實現和部署(基于 HTTP) ? 適合實時監控、系統通知、數據流更新 ? 不適合需要客戶端發消息或二進制傳輸 ? 兼容性上需考慮 IE 或企業內網瀏覽器情況