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类似就不重复了。