zoukankan      html  css  js  c++  java
  • C# MVC 实现Server-Sent Events(ApiController案例)

    (浏览器端) JS代码:

    // 建立ServerSentEvents(服务器向浏览器推送信息,简称SSE)
        $(function () {
            if (typeof (EventSource) !== "undefined") {
                // 展示服务器推送内容的DOM
                var container = document.getElementById("SseContainer");
                // 建立SSE通道
                var es = new EventSource("/api/ServerSentEvents/BuildingSse");
                // 监听SSE通道open事件
                es.onopen = function (event) {
                    container.innerHTML += "open<br/>";
                }
                // 监听SSE接收到的服务端消息
                es.onmessage = function (event) {
                    container.innerHTML += event.data + "<br/>";
                };
                // 监听SSE通道error事件
                es.onerror = function (event) {
                    container.innerHTML += "error<br/>";
                    es.close();
                }
            }
            else {
                console.log("浏览器不支持ServerSentEvents接口!");
            }
        })

    (服务器端)C# MVC Controller代码:

    using Newtonsoft.Json;
    using System;
    using System.Collections.Concurrent;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Web.Http;
    
    namespace CabinetMS.Controllers.WebApi
    {
    
        /// <summary>
        /// 自定义的SSE消息对象实体
        /// </summary>
        public class SseMessageObject
        {
            public string MsgId { get; set; }
            public string MsgData { get; set; }
        }
    
    
    
        /// <summary>
        /// 以请求方式建立SSE通道
        /// </summary>
        [RoutePrefix("api/ServerSentEvents")]
        public class ServerSentEventController : ApiController
        {
    
            // 接收浏览器请求,建立ServerSentEvents通道
            [HttpGet, Route("BuildingSse")]
            public System.Net.Http.HttpResponseMessage BuildingSse(HttpRequestMessage request)
            {
                System.Net.Http.HttpResponseMessage response = request.CreateResponse();
                response.Content = new System.Net.Http.PushStreamContent((Action<Stream, HttpContent, TransportContext>)WriteToStream, new MediaTypeHeaderValue("text/event-stream"));
                return response;
            }
    
            private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _streammessage = new ConcurrentDictionary<StreamWriter, StreamWriter>();
            public void WriteToStream(Stream outputStream, HttpContent content, TransportContext context)
            {
                StreamWriter streamwriter = new StreamWriter(outputStream);
                _streammessage.TryAdd(streamwriter, streamwriter);
            }
    
            // 建立SSE通道后,其他Controller或程序调用此方法,可以向浏览器端主动推送消息
            public static void SendSseMsg(SseMessageObject sseMsg)
            {
                MessageCallback(sseMsg);
            }
    
            // 设置向浏览器推送的消息内容
            private static void MessageCallback(SseMessageObject sseMsg)
            {
                foreach (var subscriber in _streammessage.ToArray())
                {
                    try
                    {
                        subscriber.Value.WriteLine(string.Format("id: {0}
    ", sseMsg.MsgId));
                        subscriber.Value.WriteLine(string.Format("data: {0}
    
    ", sseMsg.MsgData));
                        subscriber.Value.Flush();
                    }
                    catch
                    {
                        StreamWriter streamWriter;
                        _streammessage.TryRemove(subscriber.Value, out streamWriter);
                    }
                }
            }
        }
    }

    (服务器端)成功建立SSE通道后,向浏览器推送消息:

    // 服务端向网页端推送告警信息
    var sseMsg = new SseMessageObject();
    sseMsg.MsgId = "1101";
    sseMsg.MsgData = "自定义告警消息";
    ServerSentEventController.SendSseMsg(sseMsg);
  • 相关阅读:
    jmeter的基本功能使用详解
    服务器资源监控插件(jmeter)
    前端技术之--CSS
    前端技术之--HTML
    TCP/IP基础知识
    TCP/IP、Http的区别
    关于性能调优
    如何修改Docker已运行实例的端口映射
    Mysql 主从同步配置
    Presto的基本概念
  • 原文地址:https://www.cnblogs.com/sangzs/p/13741199.html
Copyright © 2011-2022 走看看