网站 设计 案例 简单,条友网,网页视频下载网址,佛山市 骏域网站建设微信公众号#xff1a;趣编程ACE关注可了解更多的.NET日常开发技巧#xff0c;如需源码 请公众号留言 源码;如果觉得本公众号对你有帮助#xff0c;欢迎关注【SignalR全套系列】之在.Net Core 中实现Server-Send Events消息推送1.前文链接#xff1a;【SignalR全套系列】之… 微信公众号趣编程ACE关注可了解更多的.NET日常开发技巧如需源码 请公众号留言 源码;如果觉得本公众号对你有帮助欢迎关注【SignalR全套系列】之在.Net Core 中实现Server-Send Events消息推送1.前文链接【SignalR全套系列】之在.NetCore中实现WebSocket双工通信2.简介严格来说HTTP协议无法做到服务器主动推送消息有一种变通方法就是服务器告知客户端我接下里要发送的是流信息,而SSE(Server-Send Events)就是基于这个原理来实现通信的。SSE与WebSocket作用类似都是作用于服务端与客户端之间通信的但是Websocket 是全双工通信而SSE只能是单工通信服务器向浏览器发送具体讲解可参考下面文章https://www.ruanyifeng.com/blog/2017/05/server-sent_events.html3.基于.Net Core 实现SSE首先建立一个客户端页面程序1!DOCTYPE html2html3head4 meta charsetutf-8 /5 title/title6/head7body8 script9 var source new EventSource(/see); //SSE API对象
10 // onmessage 是用来接受消息的通用回调函数
11 source.onmessage (event) console.log(接收服务端消息, event.data);
12 // onopen 当服务端与客户端建立链接后 就会触发open 事件
13 source.onopen () console.log(开始链接);
14 // 通信失败 就会触发 error事件 这时候回调onerror函数
15 source.onerror (event) console.log(event);
16
17 // 自定义事件 可以自定义需要执行的message事件 这时候通用的message事件就不会被触发了
18 source.addEventListener(custom, (e) console.log(custom, e.data));
19 /script
20/body
21/html服务端应用程序1public class Startup2 {34 private readonly Channelstring _channel; // 通道变量5 public Startup(IConfiguration configuration)6 {7 Configuration configuration;8 _channel Channel.CreateUnboundedstring(); // 创建一个无消息上限的通道9 }
10
11 public IConfiguration Configuration { get; }
12
13 // This method gets called by the runtime. Use this method to add services to the container.
14 public void ConfigureServices(IServiceCollection services)
15 {
16 services.AddControllers();
17 }
18
19 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
20 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
21 {
22 if (env.IsDevelopment())
23 {
24 app.UseDeveloperExceptionPage();
25 }
26
27 // 开启静态文件
28 app.UseStaticFiles();
29
30 app.UseRouting();
31
32 app.UseAuthorization();
33
34 app.UseEndpoints(endpoints
35 {
36 endpoints.MapControllers();
37 // 捕获路由 /send?mxxxxx
38 endpoints.Map(/send, async ctx
39 {
40 if (ctx.Request.Query.TryGetValue(m, out var m))
41 {
42 // 控制台输出
43 Trace.WriteLine(开始发送 : m);
44 // 写入到通道中去
45 await _channel.Writer.WriteAsync(m);
46 }
47 // 响应返回
48 ctx.Response.StatusCode 200;
49 });
50 });
51
52 // 自定义一个中间件
53 app.Use(async (ctx, next)
54 {
55 // 发送 /see 路由 建立链接
56 if(ctx.Request.Path.ToString().Equals(/see))
57 {
58 var response ctx.Response;
59 // 以流的形式 返回给客户端
60 response.Headers.Add(Content-Type, text/event-stream);
61
62 // 返回响应信息
63 await response.WriteAsync(event:custom\r);
64 await response.WriteAsync(data:自定义事件消息\r\r);
65
66 while(await _channel.Reader.WaitToReadAsync())
67 {
68 var message await _channel.Reader.ReadAsync();
69 Trace.WriteLine(捕捉发送消息message);
70 await response.WriteAsync($data:{message}\r\r);
71
72 await response.Body.FlushAsync();
73 }
74 }
75 });
76 }
77 }