C#下如何实现Server-Sent Event(SSE)

 更新时间:2025年07月09日 08:46:26   作者:Ping通途说 (doupoa.site)  
用户因缺乏C#实现SSE服务的参考资料,自行采用HttpListener库搭建服务端,基于协议实现非稳定性数据传输,并附代码注释分享经验,供开发者参考

1.引言

最近有个C#项目需要实现SSE服务,但在网上找了一圈都没有相关的文章,那就只能根据服务的协议自己写了。

在这里分享下,希望能帮助有需要的开发者。

2.功能实现

项目要求不高,不要求每次传输的数据必达客户端,即不追求稳定性,因此在功能实现上我使用HttpListener库作为功能的服务端。

相关协议内容请自行参照EventSource - Web API 接口参考 | MDN (mozilla.org)

各浏览器的支持情况:

新建一个类,包含以下代码,代码大部分都写了注释:

class SSEServer {
    private static HttpListener listener;

    public bool Start() {
        try {
            listener = new HttpListener();
            listener.Prefixes.Add($ "http://+:{Properties.Settings.Default.ServerPort}/");  // 监听配置文件中的IP地址,必须以`/`结尾
            listener.Start();
            listener.BeginGetContext(GetContentCallBack, listener); //当创建连接后响应的函数
        } catch (Exception ex) {
            MessageBox.Show("创建服务异常,请检查端口是否被占用:\n" + ex);
            return false;
        }
        return true;
    }

    public void Stop() {
        if (listener.IsListening) {
            listener.Stop();
        }
    }

    private void GetContentCallBack(IAsyncResult ar) {

        HttpListener _listener = ar.AsyncState as HttpListener; //异步服务,避免阻塞,也能接收多条连接
        if (_listener.IsListening) {
            HttpListenerContext context = _listener.EndGetContext(ar);
            _listener.BeginGetContext(new AsyncCallback(GetContentCallBack), _listener); // 创建新线程监听其他请求

            HttpListenerRequest req = context.Request; //获取连接请求体
            if (req.HttpMethod == "GET") //SSE只接受GET请求
            {
                HttpListenerResponse response = context.Response; //获取连接响应体
                response.StatusCode = (int) HttpStatusCode.OK; //设定状态码
                response.ContentType = "text/event-stream;charset=UTF-8"; //设定SSE的响应头
                response.AddHeader("Cache-Control", "no-cache");
                response.AddHeader("Connection", "keep-alive");
                response.AddHeader("Access-Control-Allow-Origin", "*");
                response.AddHeader("Transfer-Encoding", "chunked");
                response.ContentEncoding = Encoding.UTF8; //各种各样的响应头
                using(var stream = response.OutputStream) { //创建响应体自带的缓存流
                    while (true) {
                        try {
                            var data = Encoding.UTF8.GetBytes($ "Event: message\ndata: Hello World!\n\n"); //必须以UTF8编码发送数据
                            stream.Write(data, 0, data.Length);
                            Thread.Sleep(1000); //一秒发送一次数据
                        } catch { //有问题直接catch
                                }));
                            }
                            _listener.Close(); //关闭当前线程的连接
                            break; //当前连接响应函数运行完毕
                        }
                    }
                }
            }
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C#中的LINQ to Objects详解(2)

    C#中的LINQ to Objects详解(2)

    本文详细讲解了C#中的LINQ to Objects,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中new关键字的三种用法

    C#中new关键字的三种用法

    在C#中,new关键字具有多种不同的用途,主要包括以下三个:作为运算符,作为修饰符,作为泛型约束,文章通过代码示例将这三种用法介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • C#中Span相关的性能优化建议

    C#中Span相关的性能优化建议

    Span 是C#7.2引入的一种新类型,在.NET Core 2.1运行时中受支持,Span 提供对内存连续区域的类型安全访问,这篇文章主要给大家介绍了关于C#中Span相关的一些性能优化建议,需要的朋友可以参考下
    2021-08-08
  • C#实现双端队列的示例代码

    C#实现双端队列的示例代码

    双端队列是一种可以在两端扩展或收缩的序列化容器,本文主要介绍了C#实现双端队列的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • C#逐行读取文本文件的几种有效方法

    C#逐行读取文本文件的几种有效方法

    在C#中,我们可以使用各种方法来读取和写入文本文件,本文主要给大家介绍了C#逐行读取文本文件的几种有效方法,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2025-01-01
  • C#把数字转换成大写金额的代码实例

    C#把数字转换成大写金额的代码实例

    这篇文章主要介绍了C#把数字转换成大写金额的代码实例,例如把200转换成“贰佰元”,需要的朋友可以参考下
    2014-05-05
  • C#生成随机字符串的实例

    C#生成随机字符串的实例

    本文介绍了“C#生成随机字符串的实例”,需要的朋友可以参考一下
    2013-03-03
  • C#实现HTTP上传文件的方法

    C#实现HTTP上传文件的方法

    这篇文章主要介绍了C#实现HTTP上传文件的方法,包括了发送文件与接收文件的实现代码,具有不错的参考价值,需要的朋友可以参考下
    2014-11-11
  • 基于WPF实现Message消息提醒控件

    基于WPF实现Message消息提醒控件

    这篇文章主要介绍了如何利用WPF实现Meesage消息提醒控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2023-07-07
  • win7中C#的winForm编程使用savefiledialog不能弹出保存窗体的解决方法

    win7中C#的winForm编程使用savefiledialog不能弹出保存窗体的解决方法

    这篇文章主要介绍了win7中C#的winForm编程使用savefiledialog不能弹出保存窗体的解决方法,涉及针对线程的调用问题,是比较实用的技巧,需要的朋友可以参考下
    2014-12-12

最新评论