Server-Sent Events (SSE) 是一種讓伺服器以即時串流的方式,將更新或事件推送到客戶端的技術。與 WebSocket 不同,SSE 是單向的,只支援從伺服器向客戶端推送資料串流,因此很適合用在需要即時更新資料的情境,例如即時通知、資料串流等。本文將介紹如何在 Laravel 框架中實作 SSE。
什麼是 Server-Sent Events (SSE)?
SSE 是基於 HTTP 協定的單向資料串流技術。它讓伺服器能在與客戶端建立的持久連線上,持續把事件推送給客戶端。客戶端只需使用標準的 JavaScript API 就能接收這些事件,因此 SSE 很容易使用與整合。
示意圖:

以下範例是在 Laravel 框架中撰寫,用來即時顯示股票資料串流:
public function sseExample()
{
// 如果輸出緩衝級別大於0,清空並關閉輸出緩衝區
if (ob_get_level() > 0) {
ob_end_clean();
}
// 禁用輸出緩衝和壓縮
ini_set('output_buffering', 'off');
ini_set('zlib.output_compression', false);
// 設定 SSE 所需的 HTTP 標頭
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no'); // 防止 Nginx 緩衝 SSE 輸出
// 如果沒有緩衝級別,啟動輸出緩衝
if (ob_get_level() == 0) {
ob_start();
}
// 返回一個流式響應,用於 SSE
return response()->stream(function () {
while (true) {
// 獲取即時庫存數據
$stocks = $this->getInventory();
// 將數據以 SSE 格式發送到客戶端
echo "data: " . json_encode([
'stocks' => $stocks,
'timestamp' => now()->toIso8601String(), // 當前時間的 ISO 8601 格式
]) . "
"; // SSE 格式要求以雙換行結束每條消息
// 如果有緩衝內容,將其發送到客戶端
if (ob_get_length() > 0) {
ob_end_flush(); // 發送當前的緩衝區內容並關閉輸出緩衝
}
flush(); // 刷新輸出緩衝
// 檢查連接是否中斷,若中斷則記錄錯誤日誌並退出循環
if (connection_aborted()) {
error_log("SSE: Connection aborted");
break;
}
// 如果沒有緩衝級別,重新啟動輸出緩衝
if (ob_get_level() == 0) {
ob_start();
}
// 等待1秒鐘後再發送下一條消息
sleep(1);
}
}, 200, [
'Content-Type' => 'text/event-stream', // 設定 SSE 的內容類型
'Cache-Control' => 'no-cache', // 禁止緩存
'Connection' => 'keep-alive', // 保持連接
'X-Accel-Buffering' => 'no', // 防止 Nginx 緩衝 SSE 輸出
'Access-Control-Allow-Origin' => '*', // 允許跨域訪問
]);
}
延伸閱讀
- 【RealTime】Websocket VS SSE (Server-Sent Events):想先了解 SSE 與 WebSocket 的差異與取捨,可先讀這篇
- 【RealTime】Laravel Reverb - 官方 WebSocket Server 完整實作:需要雙向通訊時的替代方案:Laravel Reverb
No comments yet.