Html5实践之EventSource

简介:

最近尝试了一下服务器端的推送,之前的做法都是客户端轮询,定时向服务器发送请求。但这造成了我的一些困扰:

1:轮询是由客户端发起的,那么在服务端就不能判别我要推送的内容是否已经过期,因为我很难判断某个信息是否已经推送给全部的客户端,那么服务端就需要缓存大量的数据。如果数据保存在数据库,那么还要每次请求都需要查询数据库,这对数据库和系统设计都是一个很大的挑战。

2:请求的频率太高,每次的请求包中含有同样的数据,这对pc来说也许算不得什么,但是对于移动客户端来讲,这应该不是最佳的方案。尤其是遇到还要做权限判断的时候,那么服务端的逻辑和效率也会造成用户体验的降低。

好在Html5为我们提供了一种方式: Server-Sent Events包含新的HTML元素EventSource和新的MIME类型 text/event-stream 来完成我的需要。

因为是第一次接触Html5, w3school中也有对EventSource的说明和使用 。于是马上开始着手实践。

页面脚本就不用说了,按照w3school的方式即可。

var source=new EventSource("demo_sse.php");
source.onmessage=function(event)
  {
  document.getElementById("result").innerHTML+=event.data + "<br />"; };

服务端的代码也是如初一折,w3school提供了php和asp的代码:

//php方式
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); $time = date('r'); echo "data: The server time is: {$time}\n\n"; flush(); ?> //asp方式 <% Response.ContentType="text/event-stream" Response.Expires=-1 Response.Write("data: " & now()) Response.Flush() %>
  • 把报头 "Content-Type" 设置为 "text/event-stream"
  • 规定不对页面进行缓存
  • 输出发送日期(始终以 "data: " 开头)
  • 向网页刷新输出数据

也许大家应该注意到,php和asp的案例有一点不一样,就是php推送的信息一个使用了"\n\n"作为结束标志,而asp却没有。而本人实践则是用asp.net+mvc,经过测试,如果不以"\n\n"作为结束标志,那么客户端将不能接收到推送的值。还有需要特别声明一下:推送的信息格式必须为”data:内容\n\n“,否则。。。

public void Subscribe()
        {
            HttpContext.Response.ContentType = "text/event-stream";
            HttpContext.Response.CacheControl = "no-cache"; HttpContext.Response.Write("data:" + DateTime.Now.ToString()+ "\n\n"); HttpContext.Response.Flush(); }

至此,客户端应该可以收到服务端推送的值。而如此简单的结构真的可以完成我们需要的功能设计吗? 
此例我们只是推送了一个当前时间,而我们实际要推送的值是不断变化的,不然也就没有推送的必要了。

于是我想到了将订阅的请求保存起来,当需要推送的时候,在对每个请求进行循环推送,于是有了下面的代码:

public class PublishService
    {
        private static IDictionary<string, HttpResponseBase> contexts = new Dictionary<string, HttpResponseBase>(); public static void AddHttpContext(HttpContextBase context) { var token = context.GetToken(”CookieName“); if (!contexts.Keys.Contains(token)) contexts.Add(token, context.Response); } private static void Publish() { foreach (var context in contexts.Values) { context.ContentType = "text/event-stream"; context.CacheControl = "no-cache"; msg = GetData(context.GetToken("CookieName")); context.Write("data:" + msg + "\n\n"); context.Flush(); } }         public void Subscribe()         {             PublishService.AddHttpContext(HttpContext);             PublishService.Publish();         } }

可是在进行测试的时候Chrome告诉我: EventSource's response has a MIME type ("text/plain") that is not "text/event-stream". Aborting the connection.

而FF告诉我: Firefox 无法建立到 http://localhost:8000/Location/Notification/Subscribe 服务器的连接。

经过调试发现,在每次flush的时候发生异常:Server cannot flush a completed response.这究竟是为啥呢?不论是google,还是baidu,我都没能找到合适的答案,所以此案至今未结,如哪位知道请细说一二。

于是乎,我放弃了这种方式,转而就推送一个时间看看是什么效果。结果发现Chrome每隔3秒向客户端推送一次,而FF是每5秒推送一次。有了这样一个发现,那么服务端的设计就应该是另一个样子:

public void Subscribe()
        {
            var data = GetData();

            HttpContext.Response.ContentType = "text/event-stream";
            HttpContext.Response.CacheControl = "no-cache"; HttpContext.Response.Write("data:" + data + "\n\n"); HttpContext.Response.Flush(); }

服务端只需要提供一个服务GetData(),这个服务用来获取我们需要推送的信息,而根据 Server-Sent Events规范推荐如果没有其他的数据要发送,那么定期的发送keep-alive注释。 其他的事情就不用我们操心了。

这只是一个简单的使用,因为本人在使用EventSource的时候走了一些弯路,所以写出来,希望能对大家有些帮助。

求教:EventSource.onopen和EventSource.onerror每次都会触发这两个事件,而且每次得到的结果都一样,为何?

分类:  ASP.NET, Html5

本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4218187.html ,如需转载请自行联系原作者
相关文章
|
1月前
|
Web App开发 移动开发 前端开发
|
2月前
|
数据采集 数据安全/隐私保护
高效网络采集实践:使用 Haskell 和 html-conduit 下载 www.baidu.com 视频完整教程
网络采集在当今信息时代中发挥着关键作用,用于从互联网上获取数据并进行分析。本文将介绍如何使用 Haskell 进行网络编程,从数据采集到图片分析,为你提供一个清晰的指南。我们将探讨如何使用爬虫代理来确保高效、可靠的数据获取,并使用 Haskell 的强大功能来分析和处理数据。
|
11月前
|
Web App开发 编解码 前端开发
HTML躬行记(2)——WebRTC基础实践
HTML躬行记(2)——WebRTC基础实践
|
11月前
|
运维 前端开发
一文深度实践HTML表格,运维开发必备技能。基础不牢,地动山摇。跟紧步伐,复习巩固前端基础。
一文深度实践HTML表格,运维开发必备技能。基础不牢,地动山摇。跟紧步伐,复习巩固前端基础。
|
11月前
【HTML&&CSS】页面版块布局(亲身实践,帮你避坑)
【HTML&&CSS】页面版块布局(亲身实践,帮你避坑)
57 0
|
搜索推荐 前端开发 JavaScript
HTML知识积累及实践(六) - pre,混合框架
HTML知识积累及实践(六) - pre,混合框架
174 0
HTML知识积累及实践(六) - pre,混合框架
HTML知识积累及实践(五) - 表单元素
HTML知识积累及实践(五) - 表单元素
HTML知识积累及实践(五) - 表单元素
|
安全 数据安全/隐私保护
HTML知识积累及实践(四) - 表单元素
HTML知识积累及实践(四) - 表单元素
110 0
HTML知识积累及实践(四) - 表单元素
HTML知识积累及实践(三) - 列表标签
HTML知识积累及实践(三) - 列表标签
HTML知识积累及实践(三) - 列表标签
|
搜索推荐 图形学 UED
HTML知识积累及实践(二) - 标签样式
HTML知识积累及实践(二) - 标签样式
HTML知识积累及实践(二) - 标签样式