在 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 流推送消息。前端不相关。