实例介绍
【实例简介】
亲测通过,可以实时将消息发送至客户端,几乎零延时。。。,很快
不像ajax一样,一直刷。。。
最近在项目开发中使用了一种比较新的技术,SSE,即 Server-Send Event,使用它从服务器向浏览器推送数据。
传统的网页都是浏览器向服务器“查询”数据,但是很多场合,最有效的方式是服务器向浏览器“发送”数据。比如,每当收到新的电子邮件,服务器就向浏览器发送一个“通知”,这要比浏览器按时向服务器查询(polling)更有效率。
服务器发送事件(Server-Sent Events,简称SSE)就是为了解决这个问题,而提出的一种新API,部署在EventSource对象上。目前,除了IE,其他主流浏览器都支持。
简单说,所谓SSE,就是浏览器向服务器发送一个HTTP请求,然后服务器不断单向地向浏览器推送“信息”(message)。这种信息在格式上很简单,就是“信息”加上前缀“data: ”,然后以“\n\n”结尾。
SSE与WebSocket有相似功能,都是用来建立浏览器与服务器之间的通信渠道。两者的区别在于:
WebSocket是全双工通道,可以双向通信,功能更强;SSE是单向通道,只能服务器向浏览器端发送。
WebSocket是一个新的协议,需要服务器端支持;SSE则是部署在HTTP协议之上的,现有的服务器软件都支持。
SSE是一个轻量级协议,相对简单;WebSocket是一种较重的协议,相对复杂。
SSE默认支持断线重连,WebSocket则需要额外部署。
SSE支持自定义发送的数据类型。
从上面的比较可以看出,两者各有特点,适合不同的场合。
提示:除了IE之外,几乎所有浏览器均支持 SSE
【实例截图】
SSE浏览器 兼容性如下:
【核心代码】
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Web.Http; using System.IO; using System.Net.Http.Headers; using System.Net; using System.Collections.Concurrent; using System.Threading; using Newtonsoft.Json; using System.Diagnostics; using System.Threading.Tasks; using Strathweb.HTML5push.Models; namespace Strathweb.HTML5push.Controllers { //如果想 每个聊天室 都独立显示聊天内容的话,则需要将 _streammessage 按照聊天室编号 存储到 dictionary中 public class ChatController : ApiController { private static readonly ConcurrentQueue<StreamWriter> _streammessage = new ConcurrentQueue<StreamWriter>(); public HttpResponseMessage Get(HttpRequestMessage request) { HttpResponseMessage response = request.CreateResponse(); response.Content = new PushStreamContent(OnStreamAvailable, "text/event-stream"); return response; } public void Post(Message m) { m.dt = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"); MessageCallback(m); } public static void OnStreamAvailable(Stream stream, HttpContentHeaders headers, TransportContext context) { StreamWriter streamwriter = new StreamWriter(stream){ AutoFlush = true }; streamwriter.WriteLine("data:init \n"); streamwriter.WriteLine(""); streamwriter.Flush(); _streammessage.Enqueue(streamwriter); } private static void MessageCallback(Message m) { var i = 0; foreach (var subscriber in _streammessage) { i ; try { subscriber.WriteLine("data:" JsonConvert.SerializeObject(m) "\n"); subscriber.WriteLine(""); subscriber.Flush(); } catch (Exception ex) { var j = i; } } } } //下为异步方式(也亲测通过了),需更改项目属性为 .net framework 4.5 //public class ChatController : ApiController //{ // private static object locker = new object(); // private static readonly List<StreamWriter> Subscribers = new List<StreamWriter>(); // public HttpResponseMessage Get(HttpRequestMessage request) // { // var response = new HttpResponseMessage // { // Content = new PushStreamContent(async (respStream, content, context) => // { // var subscriber = new StreamWriter(respStream) // { // AutoFlush = true // }; // lock (locker) // { // Subscribers.Add(subscriber); // } // await subscriber.WriteLineAsync("data: \n"); // }, "text/event-stream") // }; // return response; // } // public async Task Post(Message m) // { // m.dt = DateTime.Now.ToShortDateString(); // await MessageCallback(m); // } // private static async Task MessageCallback(Message m) // { // for (var i = Subscribers.Count - 1; i >= 0; i--) // { // try // { // await Subscribers[i].WriteLineAsync("data:" JsonConvert.SerializeObject(m) "\n"); // await Subscribers[i].WriteLineAsync(""); // await Subscribers[i].FlushAsync(); // } // catch (Exception) // { // lock (locker) // { // Subscribers.RemoveAt(i); // } // } // } // } //} }
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论