C#实现SSE(Server-Sent Events)服务端和客户端的示例代码

 更新时间:2024年03月07日 11:38:20   作者:j10n  
这篇文章主要为大家详细介绍了C#实现SSE(Server-Sent Events)服务端和客户端的相关知识,文中的示例代码讲解详细,有需要的小伙伴可以参考下

效果图

服务端不停发送当前时间。

服务端代码: 

using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Threading;
 
namespace SSEserver
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpListener listener = new HttpListener();
            listener.Prefixes.Add("http://localhost:8080/");
            listener.Start();
 
            Console.WriteLine("Server is running...");
 
            while (true)
            {
                HttpListenerContext context = listener.GetContext();
                ThreadPool.QueueUserWorkItem((_) =>
                {
                    SendEvent(context);
                });
            }
        }
 
        static void SendEvent(HttpListenerContext context)
        {
            try
            {
                context.Response.ContentType = "text/event-stream";
                context.Response.StatusCode = 200;
                context.Response.Headers.Add("Cache-Control", "no-cache");
                context.Response.Headers.Add("Connection", "keep-alive");
 
                while (true)
                {
                    string message = $"data: {DateTime.Now.ToString("HH:mm:ss")}\n\n";
                    byte[] bytes = Encoding.UTF8.GetBytes(message);
                    context.Response.OutputStream.Write(bytes, 0, bytes.Length);
                    context.Response.OutputStream.Flush();
                    Thread.Sleep(1000); // 每秒发送一次消息
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
            finally
            {
                context.Response.Close();
            }
        }
    }
}

客户端不停接收服务端发送的时间。

客户端代码: 

using System;
using System.IO;
using System.Net;
using System.Text;
namespace SSEclient
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string url = "http://localhost:8080/sse_endpoint"; // SSE endpoint URL
 
            using (HttpClient client = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                request.Headers.Add("Accept", "text/event-stream");
 
                using (HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead))
                {
                    response.EnsureSuccessStatusCode();
 
                    using (var responseStream = await response.Content.ReadAsStreamAsync())
                    using (var reader = new System.IO.StreamReader(responseStream))
                    {
                        while (!reader.EndOfStream)
                        {
                            string line = await reader.ReadLineAsync();
 
                            if (!string.IsNullOrWhiteSpace(line))
                            {
                                Console.WriteLine(line);
                                // Handle the received SSE event here
                            }
                        }
                    }
                }
            }
        }
    }
}

方法补充

除了上文的方法,小编还为大家整理了其他C#实现SSE(Server-Sent Events)的方法,希望对大家有所帮助

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}\n", sseMsg.MsgId));
                    subscriber.Value.WriteLine(string.Format("data: {0}\n\n", 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);

到此这篇关于C#实现SSE(Server-Sent Events)服务端和客户端的示例代码的文章就介绍到这了,更多相关C# SSE服务端和客户端内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c# EPPlus秘籍之Excel实现图表导出

    c# EPPlus秘籍之Excel实现图表导出

    这篇文章主要为大家介绍了c# EPPlus秘籍之Excel实现图表导出示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 解析C# 程序结构

    解析C# 程序结构

    在我们学习 C# 编程语言的基础构件块之前,让我们先看一下 C# 的最小的程序结构,以便作为接下来章节的参考
    2021-07-07
  • C#绘制饼状图和柱状图的方法

    C#绘制饼状图和柱状图的方法

    这篇文章主要为大家详细介绍了C#绘制饼状图和柱状图的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • C#实现win10 uwp 右击浮出窗在点击位置

    C#实现win10 uwp 右击浮出窗在点击位置

    本文主要让MenuFlyout出现在我们右击位置。我们建一个ListView,然后绑定后台,在我们ListView要右击显示我们的浮出,要求我们的浮出在我们点击位置
    2016-10-10
  • C# 定时器定时更新的简单实例

    C# 定时器定时更新的简单实例

    这篇文章主要介绍了C#中定时器定时更新的简单实例。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • 在C#中调用Windows防火墙界面的常见方式

    在C#中调用Windows防火墙界面的常见方式

    在 C# 中调用 Windows 防火墙界面(基础设置或高级安全设置),可以使用 进程启动(Process.Start) 或 Win32 API 来实现,所以本文给大家介绍了C#调用Windows防火墙界面的常见方式,需要的朋友可以参考下
    2025-11-11
  • 基于C#实现屏幕墙并同时监控多个电脑桌面

    基于C#实现屏幕墙并同时监控多个电脑桌面

    这篇文章主要为大家详细介绍了如何基于C#实现一个屏幕墙,用户可在监控端实时查看多个被监控电脑屏幕的内容,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-08-08
  • C#操作注册表的方法

    C#操作注册表的方法

    这篇文章介绍了C#操作注册表的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#实现DataList里面嵌套DataList的折叠菜单

    C#实现DataList里面嵌套DataList的折叠菜单

    这篇文章主要介绍了C#实现DataList里面嵌套DataList的折叠菜单,以实例形式详细分析了DataList嵌套实现折叠菜单所涉及的JavaScript、HTML与C#相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • C#实现给Word每一页设置不同图片水印

    C#实现给Word每一页设置不同图片水印

    Word中设置水印时,可加载图片设置为水印效果,但通常添加水印效果时,会对所有页面都设置成统一效果。本文将利用C#实现给Word每一页设置不同图片水印的效果,需要的可以参考一下
    2022-02-02

最新评论