有些時候,我們想在前端網頁顯示一些 "會動的資料" 像是
系統狀態更新、線上使用者數、Log 即時推送、客戶通知更新(消息通知)..之類的
知道你第一前間會想到 web socket 或是 SignalR,但是我們只有單向(Server-> Client)
我看到一個有趣的做法 就是透過 SSE ( Server-Sent Events )
SSE= 後端保持一條 HTTP 連線 → 持續往前端推資料
因為我們有時候需要的傳遞資料小,而且是單向,也不用一堆套件就可以用這方法
這邊我們就來簡單實做一下,後端我們先建立一個 EndPoint
Program.cs 加入
app.MapGet("/events", async context =>
{
context.Response.Headers.Append("Content-Type", "text/event-stream; charset=utf-8");
context.Features.Get()?
.DisableBuffering();
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync())
{
await context.Response.WriteAsync($"data:Server 時間-"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"\n\n");
await context.Response.Body.FlushAsync();
}
});
設定 Content-Type = text/event-stream ,用 PeriodicTimer 每秒 tick 一次
每次 tick 就寫一行 Server 時間
FlushAsync() 讓資料立刻送出去
\n\n 視為單筆資料結束
前端如何接收
<script>
const evt = new EventSource("/events");
evt.onmessage = (e) => {
console.log("收到伺服器事件:", e.data);
}
</script>
瀏覽器會自動重連、自動處理斷線、自動處理 SSE 格式、自動排除 duplicated event
結果:
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:36
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:37
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:38
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:39
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:40
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:41
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:42
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:43
(索引):65 收到伺服器事件: Server 時間-2025-08-12 13:19:44
結論-
這段 SSE 實作最大的收穫就是:如果你只是需要後端單向推資料到前端,其實不必搬出 WebSocket 或 SignalR
SSE 本身就夠輕、夠穩、也夠簡單。後端維持一條連線、前端一個 EventSource,就能完成即時更新。對於小量、單向、即時的場景來說,SSE 幾乎是最輕鬆的選擇。