[C#] 用 .NET 實作 SSE:最簡單的即時推播,不用 WebSocket、也不用 SignalR

2025-08-13

有些時候,我們想在前端網頁顯示一些 "會動的資料" 像是

系統狀態更新、線上使用者數、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<Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature>()? .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 視為單筆資料結束


前端如何接收

&lt;script&gt; const evt = new EventSource(&quot;/events&quot;); evt.onmessage = (e) =&gt; { console.log(&quot;收到伺服器事件&#65306;&quot;, e.data); } &lt;/script&gt;


瀏覽器會自動重連、自動處理斷線、自動處理 SSE 格式、自動排除 duplicated event

結果:

(索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:36 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:37 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:38 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:39 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:40 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:41 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:42 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:43 (索引):65 收到伺服器事件&#65306; Server 時間-2025-08-12 13:19:44


結論-

這段 SSE 實作最大的收穫就是:如果你只是需要後端單向推資料到前端,其實不必搬出 WebSocket 或 SignalR

SSE 本身就夠輕、夠穩、也夠簡單。後端維持一條連線、前端一個 EventSource,就能完成即時更新。對於小量、單向、即時的場景來說,SSE 幾乎是最輕鬆的選擇。


當麻許的碎念筆記 2014 | Donma Hsu Design.