在客户端开发时可以通过轮询的方式拿到服务器端的数据,同时在客户端开发时,如果是将客户端也作为服务器端,那么之间的通讯将会十分简单。有个逗比的小伙伴想要用我的客户端魔改,但是他又不想学习什么知识,此时他需要拿到我客户端的实时信息,好在他知道一点 html 的知识,于是让我通过服务器发送事件 Server-Sent Events 而他写一个简陋的 html 去拿到我客户端的数据 这是一个简陋的开发端的工具,开源的好处就是,你觉得不爽,自己改哇。自己改不动就等开发者下班协助啦,本文就使用一个简单的方式在 asp dotnet core 实现服务器发送事件。虽然标题是 asp dotnet core 而实际上我的软件是一个桌面端软件
其实服务器发送事件 Server-Sent Events 原理就是在请求发送的 stream 设置 Content-Type
为 text/event-stream
然后不断写入数据就可以了
新建一个控制器,在控制台里面的调用方法,注意需要是 get 方法哦(其实没有限制)这样写起来才简单
[ApiController]
[Route("[controller]")]
public class FooController : ControllerBase
{
[HttpGet]
public async Task Get()
{
}
通过 Response 属性可以拿到请求,在 Header 添加 Content-Type
这样就可以告诉调用者返回的是服务器发送事件
var response = Response;
response.Headers.Add("Content-Type", "text/event-stream");
不断给调用者发送数据的方法就是不断写入数据
await response
.WriteAsync($"data: 当前时间 {DateTime.Now} {Thread.CurrentThread.ManagedThreadId}\r\r");
注意写入数据的格式,要求是 data: 信息 \r\r
如果格式不对,那么调用方是接收不到数据
写入数据之后需要发送
response.Body.Flush();
如不断告诉调用方更新时间可以这样写
[HttpGet]
public async Task Get()
{
var response = Response;
response.Headers.Add("Content-Type", "text/event-stream");
for (var i = 0; ; ++i)
{
await response
.WriteAsync($"data: 当前时间 {DateTime.Now} {Thread.CurrentThread.ManagedThreadId}\r\r");
response.Body.Flush();
await Task.Delay(TimeSpan.FromSeconds(1));
}
}
上面的代码请不要放在实际项目,因为方法被调用就不会停下
此时调用者就可以使用简单的方法拿到服务器发送的数据
本文代码放在 github 下载代码运行,访问 http://localhost:端口/index.html
就可以看到网页不断刷新时间
当然更好的通讯方法是通过 Pipe 的方式通讯,可选框架是 WCF 等
如果是现代的开发,建议使用 SignalR 的方法发送数据,其实 SignalR 底层传输是 Web Socket, Server Sent Events 和 Long Polling 方法
.net core HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例)
本文开始标题是 WPF 发送Server-Sent Events给其他进程,但是实际上没有用到 WPF 的任何内容,于是修改了标题。如果你是因为工作需要用到这个技术,搜到本文,如果还有精力,那么我推荐你看一下 WCF 或 SignalR 的方法。如果没有,那么本文的代码也请不要抄,因为上面的代码会让方法不断运行
本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/asp-dotnet-core-%E5%AE%9E%E7%8E%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8F%91%E9%80%81%E4%BA%8B%E4%BB%B6-Server-Sent-Events-%E7%AE%80%E5%8D%95%E6%96%B9%E5%BC%8F.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 lindexi (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。