实例介绍
【实例简介】
亲测通过,可以实时将消息发送至客户端,几乎零延时。。。,很快
不像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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论