在 ASP.Net core Web API 中使用 HTML 伺服器傳送事件的小範例。
該應用程式是一個每秒自動增加的計數器。使用者可以暫停或恢復計數器,或將其設定為給定值。
計數器儲存在伺服器的記憶體中。瀏覽器會話中的變更將傳播到所有其他開啟的會話。
伺服器發送事件是一個 Web API,可讓您使用 HTTP 流將訊息從服務器推送到 JavaScript。
這不是從伺服器推送訊息的唯一方法,但它確實是一種簡單且非常優雅的方法。
使用伺服器發送事件的 Javascript 程式碼位於檔案stream.js 中,如下所示:
function readStream()
{
const evtSource = new EventSource('/Counter/Stream');
evtSource.onmessage = function(event) {
const el = document.getElementById('counter');
const { value } = JSON.parse(event.data);
el.textContent = value;
}
}
該儲存庫包含一個小型獨立的 Web 應用程序,可用作參考或樣板程式碼,用於透過 ASP.Net Core 後端使用伺服器發送的事件。
HTTP 流端點的實作可以在 CounterController.cs 中找到,如下所示。它改編自 StackOverflow 的答案。
[HttpGet]
[Route("Stream")]
public async Task StreamCounter(CancellationToken cancellationToken)
{
_logger.LogInformation("Start counter streaming.");
Response.StatusCode = 200;
Response.Headers.Add("Content-Type", "text/event-stream");
_counter.CounterUpdated += StreamValue;
while (!cancellationToken.IsCancellationRequested) {
await Task.Delay(1000);
}
_counter.CounterUpdated -= StreamValue;
_logger.LogInformation("Stop counter streaming.");
async void StreamValue(object sender, int value)
{
var messageJson = JsonConvert.SerializeObject(_counter, _jsonSettings);
await Response.WriteAsync($"data:{messageJson}nn");
await Response.Body.FlushAsync();
}
}
狀態(計數器)儲存在單例服務 PersistentCounter 中。
每次更新計數器值時,服務都會觸發一個事件。控制器訂閱此事件並在每次變更後將新值推送到客戶端。
要運行該應用程序,只需在儲存庫的主資料夾中鍵入以下命令:
dotnet build
dotnet run
確保您之前安裝了.NET 5 SDK。
開啟瀏覽器並導航至https://localhost:5001
。
您將收到證書錯誤,因為我沒有使用有效的註冊證書。
以下只是一些提供一些背景資訊的背景資訊。您無需閱讀它即可理解程式碼。
該儲存庫只是有關如何將現有桌面應用程式移植到 Web 應用程式的概念驗證的一小部分。
使用 ASP.Net 作為前端可能是最簡單的方法。然而,我真的很喜歡 React/Redux 進行 Web 開發,而且我對它的經驗也比 ASP 更有經驗。所以我決定使用 ASP 作為 REST 後端,並使用 React 作為前端。
慣用的.Net 應用程式大量使用了事件模式。
我的想法是編寫某種中間件,它訂閱應用程式內部產生的所有事件,將它們序列化為 JSON,並使用Server Sent Events將它們推送到客戶端。
客戶端將透過調度一些 Redux 操作來對事件做出反應,這將更新前端狀態。
後端將為與前端的所有其他互動公開 REST 端點。沒什麼特別的。
中間件將扮演與此儲存庫中的單例服務 PersistentCounter 相同的角色。
該存儲庫僅使用普通的 JavaScript。沒有 React 或 Redux。我在這裡的目的只是評估透過 HTTP 流推送訊息。前端不相關。