使用ASP.NET MVC和ASP.NET WebForms实现SSE

SSE(Server-Sent Events) 又称为服务器发送事件,是Html5的一种特性,功能与WebSocket类似,都是用来做消息推送的,主要的不同点在于它只能做单向通讯,而WebSocket可以做双向通讯,它的优势在于使用起来很简单,无需引用其他类库就能实现,因为它是基于HTTP协议的。

网上显示搜了一圈发现大部分的文章都是用ASP.NET Core来实现了,只好参考别人的代码后拿来改了改也能实现一样的效果。

ASP.NET MVC:

1. 新建一个控制器SSEController,新建一个视图SSE\Index.cshtml

2. 在SSEControl中新建一个方法SentNotice,代码如下:

    public class SSEController : Controller
    {
        public int LastEventID { get; set; }

        /// <summary>
        /// 主页控制器.
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 服务器往客户端推送消息的服务.
        /// </summary>
        /// <returns></returns>
        public ContentResult SentNotice()
        {
            try
            {
                HttpContext.Response.ContentEncoding = Encoding.UTF8;
                HttpContext.Response.ContentType = "text/event-stream; charset=utf-8";  // 设置报文头为text/event-stream
                HttpContext.Response.Headers["Cache-control"] = "no-cache";  // 规定不对页面进行缓存
                HttpContext.Response.Headers["Keep-alive"] = "timeout=5";
                HttpContext.Response.Expires = -1;
                HttpContext.Response.StatusCode = 200;
                for (int i = 0; ;i ++)
                {
                    try
                    {
                        LastEventID = i;    // 设置Last-Event-Id的意义在于保证数据的完整性,因为SSE有自动断点重连的的机制,重连成功会将这个属性回传到服务器,服务器接收到这个后就可以做某些处理。
                        HttpContext.Response.Write(string.Format("id:{1}\nevent:message\ndata:{0}\n\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), LastEventID));
                        Response.Flush();
                    }
                    catch
                    {

                    }

                    Thread.Sleep(3000);
                }
            }
            catch
            {

            }

            return Content("");
        }
    }

Index.cshtml的代码如下:


@{
    Layout = null;
}
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>IndexView</title>
</head>
<body>
    <div id="eventstream">
    </div>
    <script>
        window.onload = function ()
        {
            // 调用一个SSE服务
            if (typeof (EventSource) !== "undefined") {
                console.log("浏览器支持 Server-Sent事件");
                var source = new EventSource("/SSE/SentNotice");
                source.onopen = function (event) {
                    console.log("连接成功");
                }

                source.onmessage = function (event) {
                    // 接收到服务器推送的数据
                    console.log(event);
                };

                source.onerror = function (event) {
                    // 连接状态异常
                    if (event.target.readyState === EventSource.CLOSED) {
                        console.log('连接断开');
                    } else if (event.target.readyState === EventSource.CONNECTING) {
                        console.log('正在连接...');
                    }
                }

                // 关闭连接
                // source.close();
            }
            else {
                console.log("浏览器不支持 Server-Sent事件");
            }
            
        };
    </script>
</body>
</html>

效果如下:

 

ASP.NET WebForms:

1. 新建SSE目录,在SSE目录中新建SSEHandler.ashx作为服务,Index.aspx作为前端页面

SSEHandler.ashx代码如下:

    /// <summary>
    /// SSEHandler 的摘要说明
    /// </summary>
    public class SSEHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                context.Response.ContentEncoding = Encoding.UTF8;
                context.Response.ContentType = "text/event-stream; charset=utf-8";  // 设置报文头为text/event-stream
                context.Response.Headers["Cache-control"] = "no-cache";  // 规定不对页面进行缓存
                context.Response.Headers["Keep-alive"] = "timeout=5";
                context.Response.Expires = -1;
                context.Response.StatusCode = 200;
                for (int i = 0; ;)
                {
                    try
                    {
                        context.Response.Write(string.Format("id:11\nevent:message\ndata:{0}\n\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                        context.Response.Flush();
                    }
                    catch
                    {

                    }

                    Thread.Sleep(3000);
                }
            }
            catch
            {

            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

Index.aspx的代码和Index.cshtml类似就不重复了。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值