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

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每次都会触发这两个事件,而且每次得到的结果都一样,为何?

Html5实践之EventSource相关推荐

  1. HTML5实践 -- 使用css装饰你的图片画廊 - part2

    转载请注明原创地址:http://www.cnblogs.com/softlover/archive/2012/11/20/2779893.html 在上一讲中,我们的解决方案使用到了jquery去创 ...

  2. HTML5实践 -- 三步实现响应式设计

    HTML5实践 -- 三步实现响应式设计 响应式web设计现在已经不是一个难事了,如果你还不熟悉他,可以参看我的文章<HTML5实践 -- 流式响应式设计>.如果你是一个初学者,可能响应式 ...

  3. HTML5实践 -- 使用css装饰你的图片画廊

    转载请注明原创地址:http://www.cnblogs.com/softlover/archive/2012/11/20/2779890.html 本节课我们将介绍,如何使用css在不修改图片源的前 ...

  4. HTML5实践 -- 介绍css3中的几个属性:text-shadow、box-shadow 和 border-radius

    转载请注明原创地址:http://www.cnblogs.com/softlover/archive/2012/11/21/2779873.html 今天我们的内容是css3的text-shadow. ...

  5. html5实践开发教程,HTML5基础与实践教程

    HTML5基础与实践教程 语音 编辑 锁定 讨论 上传视频 <HTML5基础与实践教程>是2010年4月机械工业出版社出版的图书,作者是云翔,刘猛猛,欧阳植昊. 书    名 HTML5基 ...

  6. 把图片做成html,HTML5实践-图片设置成灰度图

    以前,在web上要显示灰度图片的话,只有手工使用图片软件转换.但是现在借助于html5的canvas可以实现这个过程,而不需要再借助图片编辑软件了.我用html5和jquery做了一个demo,来展示 ...

  7. HTML5实践之歌词同步播放器

    歌曲播放我们会发现他的兼容性不是很好,譬如IE上能播放的flash播放器,再firfox或者chrome上就不是很好的应用了,因为有插件的阻碍!HTML5的出现让这一切成为了可能,但是播放器虽然播放了 ...

  8. php 歌词同步,HTML5实践之歌词同步播放器的示例代码分享

    歌曲播放我们会发现他的兼容性不是很好,譬如IE上能播放的flash播放器,再firfox或者chrome上就不是很好的应用了,因为有插件的阻碍!HTML5的出现让这一切成为了可能,但是播放器虽然播放了 ...

  9. html5实践报告总结,社会实践总结报告500字

    社会实践总结报告500字 社会实践是讲人类认识世界.改造世界的各种活动的总和.即全人类或大多数人从事的各种活动,包括认识世界.利用世界.享受世界和改造世界等等.下面是社会实践总结,大家一起来借鉴一下! ...

最新文章

  1. 函数指针到文本反汇编
  2. 一个算法同时解决两大CV任务,让目标检测和实例分割互相帮助,地平线实习生论文被AAAI 2020收录...
  3. 走近虚拟机——McAfee研究员孙冰谈虚拟机技术和虚拟机安全
  4. win10电脑服务器在哪个文件夹下,Win10桌面背景在哪个文件夹?Win10桌面背景所在文件夹介绍...
  5. dnSpy 强大的.Net反编译软件
  6. Jquery getJSON方法分析(二)
  7. Python实现基于HDFS的云盘系统
  8. 盖得化工--selenium翻页测试
  9. 在Windows环境下为Python 2.5安装SSL模块
  10. python property 与get/set方法详解
  11. 2021年长安杯电子数据取证比赛复盘完整版(wp)
  12. 企业估值研究到底从何处着手?
  13. 电脑只能上QQ不能上网怎么办
  14. 第一章概述-------第一节--1.2互联网概述
  15. Android BLE GATT CONN LMP TIMEOUT 0x22
  16. 武林外传之勇夺金掌柜 【安卓游戏】
  17. 实验三 使用CSS3
  18. 北京国际康培计算机技术学校,2019年IB统考成绩最新汇总,北京哪所国际学校分数最高?...
  19. Linux下学习DB2命令的笔记
  20. 129.s1-拦截黑名单的电话,Android Studio使用aidl

热门文章

  1. C++二叉搜索树(Binary Search Tree)(附完整源码)
  2. C++检测步骤与示例
  3. C++ deque方法
  4. QT的QBoxPlotSeries类的使用
  5. C语言函数调用的原理
  6. 家庭财务管理系统_我31岁,30天整理出这些财务笔记干货,从宝妈成功逆袭成为会计...
  7. linux 命令行 ctrl z,Linux操作系统下运行命令时CTRL+Z的作用
  8. php安全配置总结,php安全配置详细说明(1/2)_PHP教程
  9. Spring+mongodb集群集成(吐血教程) 转自:http://blog.csdn.net/qq_16497617/article/details/52817335
  10. 01_基于应用拆分的技术架构