server-sent events--One Way Messaging

  

  


  

  允许网页获得来自服务器的更新,并且自动更新

  • Server-Sent Events: allow a web page to get updates from a server
  • This was also possible before, but the web page would have to ask if any updates were available. With server-sent events, the updates come automatically.
  • Examples: Facebook/Twitter updates, stock price updates, news feeds, sport results, etc.

  原理如下:

  1. client利用regular http请求webpage
  2. 请求的webpage 执行javascript脚本,open a connection to server.
  3. 当有新的信息时服务器将信息发送给client

浏览器支持情况:

desktop:

mobile:

使用入门:


receive Server-Sent Event Notifications: (接收Server-sent事件通知)

利用EventSource的onmessage获取消息

EventSource事件如下:

onopen   当服务器连接被打开时   When a connection to the server is opened

onmessage   当接收到消息       When a message is received

onerror

创建和关闭

var source = new EventSource();

source.close();

数据格式:

data: My message\n\n

如果数据比较长时,可以采用多行data:然后使用event.data.split('\n').join('')组合数据

data: first line\n
data: second line\n\n

简单例子:

eg:html页面:

<!DOCTYPE html>
<html>
<head>
<style>
div{
border-radius: 10px;
border: 2px solid pink;
}
</style>
</head>
<body>
<h1></h1>
<div id="result"></div> <script>
if(typeof(EventSource)!=="undefined") //监测是否支持EventSource
{
var source=new EventSource("sseServer.jsp");
source.onmessage=function(event)
{
document.getElementById("result").innerHTML+=event.data + "<br />";
};
}
else
{
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
}
</script> </body>
</html>

服务器sseServer.jsp代码:

<%@ page language="java" contentType="text/event-stream; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Date"%>
<%@ page import="java.io.*"%>
<%
Date date = new Date();
System.out.println(date);
response.setContentType("text/event-stream"); //设置contentType
response.setHeader("Cache-Control", "no-cache"); //设置不缓存
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
PrintWriter pw = response.getWriter();
pw.print("data: today is "+date.toString()+" wish you happy~~~"); //注意必须以data:开头
pw.flush();
%>

结果:


eg2:传送多行数据:

if(typeof(EventSource)!=="undefined"){
var source=new EventSource("multiLineServer.jsp");
source.onmessage=function(event)
{
document.getElementById("result").innerHTML+=event.data.split('\n').join('') + "<br />";
}; }else{
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
}
    Date date = new Date();
System.out.println(date);
response.setContentType("text/event-stream");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
PrintWriter pw = response.getWriter();
pw.println("data: today is "+date.toString()+" wish you happy~~~");
pw.println("data: have a nice day");
pw.flush();

结果如下:


eg3:以json格式封装数据:

if(typeof(EventSource)!=="undefined"){
var source=new EventSource("jsonServer.jsp");
source.onmessage=function(event)
{ var data = JSON.parse(event.data);
document.getElementById("result").innerHTML+="date:"+data.date + "<br />";
document.getElementById("result").innerHTML+="name:"+data.name + "<br />";
}; }else{
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
}

server:

Date date = new Date();
System.out.println(date);
response.setContentType("text/event-stream");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma","no-cache");
response.setDateHeader("Expires",0);
PrintWriter pw = response.getWriter();
pw.println("data: {");
pw.println("data: \"date\":\""+date.toString()+"\",");
pw.println("data: \"name\":\"wish\"");
pw.println("data:}"); pw.flush();

结果如下:

添加监听事件:

事件如下:

message

open

error

eg:

if(typeof(EventSource)!=="undefined"){
var source=new EventSource("sseServer.jsp");
source.addEventListener('message',function(event){
//Connection was opended
document.getElementById("result").innerHTML+=event.data + "<br />"; },false);
}else{
document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
}

服务器端代码相同,结果与上例相同:

open和error事件如下:

source.addEventListener('open', function(event) {
// Connection was opened.
}, false); source.addEventListener('error', function(event) {
if (event.readyState == EventSource.CLOSED) {
// Connection was closed.
}
}, false);

 注意:当连接关闭时,浏览器会自动在3秒后重新连接,可以在服务器端设置时间

设置事件id和reconnect time


设置id

在stream前加上id:, 可以让浏览器跟踪最后一次触发的事件,如果服务器死掉时,可以在新的请求设置HTTP header,通过event.lastEventId可以获取该值

eg:

id: 1222\n
data: ...\n

设置reconnection time

默认是在连接关闭3秒后reconnect,可以通过设置stream更改

eg:设置5秒

retry: 50000\n
data: ......\n

自定义事件名称

eg:设置update事件

stream:

event: update\n
data: {"username": "wish", "emotion": "happy"}\n

js:

source.addEventListener('update', function(event) {
var data = JSON.parse(event.data);
console.log(data.username + ' is now ' + data.emotion);
}, false);

Security

在stream中增加origin

source.addEventListener('message', function(event) {
if (event.origin != 'http://cnblogs.com') {
//................
return;
}
...
}, false);

其他请参考:Cross-document messaging security

polling相关技术比较


Regular http:

  1. client发送请求.
  2. server计算
  3. server sends the response to the client.


AJAX Polling:

  1. client利用regular http请求webpage
  2. 请求的webpage 执行javascript脚本以一定间隔向服务器请求file
  3. server计算每个reqponse,发送给client


AJAX Long-Polling:

  1. client利用regular http请求webpage
  2. 请求的webpage 执行javascript脚本向服务器请求file
  3. 服务器并不立即响应,而是等到有新的信息时才响应
  4. client收到response后立即发送新的请求,重复上面过程


HTML5 Websockets:

  1. client利用regular http请求webpage
  2. 请求的webpage 执行javascript脚本,open a connection to server.
  3. 有新的信息时服务器和客户端可以相互发送信息(Real-time traffic from the server to the client and from the client to the server)

  4. 使用请查看:https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications


Comet:

Comet 是HTML5技术之前使用streaming 和long-polling来实现实时应用程序的技术(Streaming and long polling for responsive communication between your server and client)更多了解http://www.ibm.com/developerworks/web/library/wa-reverseajax1/index.html

Comet is a web application model where a request is sent to the server and kept alive for a long time, until a time-out or a server event occurs. When the request is completed, another long-lived Ajax request is sent to wait for other server events. With Comet, web servers can send the data to the client without having to explicitly request it. 

相关博文:HTML5 Web socket和socket.io

参考:http://www.w3schools.com/html/html5_serversentevents.asp

    http://jaxenter.com/tutorial-jsf-2-and-html5-server-sent-events-42932.html

     http://www.html5rocks.com/en/tutorials/eventsource/basics/

      http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#authors

      http://stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet

    http://www.ibm.com/developerworks/web/library/wa-reverseajax1/index.html

SSE及相关技术(web sockets, long polling等)的更多相关文章

  1. Ajax、Comet、HTML 5 Web Sockets技术比较分析

    最近因为考虑研究B/S结构网站即时消息处理 参考了 JAVA怎么样实现即时消息提醒http://bbs.csdn.net/topics/330015611http://www.ibm.com/deve ...

  2. 关于Web开发里并发、同步、异步以及事件驱动编程的相关技术

    一.开篇语 我的上篇文章<关于如何提供Web服务端并发效率的异步编程技术>又成为了博客园里“编辑推荐”的文章,这是对我写博客很大的鼓励,也许是被推荐的原因很多童鞋在这篇文章里发表了评论,有 ...

  3. Java Web相关技术(汇聚页)

    Java Web相关技术(汇聚页) 初学Java Web(2)——搭建Java Web开发环境

  4. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  5. 【原】http缓存与cdn相关技术

    摘要:最近要做这个主题的组内分享,所以准备了一个星期,查了比较多的资料.准备的过程虽然很烦很耗时间,不过因为需要查很多的资料,因此整个过程下来,对这方面的知识影响更加深刻.来来来,接下来总结总结 一 ...

  6. 关于全站https必要性http流量劫持、dns劫持等相关技术

    关于全站https必要性http流量劫持.dns劫持等相关技术 微信已经要求微信支付,申请退款功能必须12月7号之前必须使用https证书了(其他目前为建议使用https),IOS也是2017年1月1 ...

  7. SAAS相关技术要点

    这篇文章本来是我们开发组内部用的一个小文档.因为我们公司以前没有做SAAS的经验,就成立了一个小组做一做这方面的技术前探,我是成员之一.这篇文档想从宏观的层面把开发一个SAAS应用所要用到的技术点稍微 ...

  8. Websocket 与代理服务器如何交互? How HTML5 Web Sockets Interact With Proxy Servers

    How HTML5 Web Sockets Interact With Proxy Servers Posted by Peter Lubberson Mar 16, 2010 With the re ...

  9. http缓存与cdn相关技术

    阅读目录 一 http缓存 二.Http缓存概念解析 三.cdn相关技术 摘要:最近要做这个主题的组内分享,所以准备了一个星期,查了比较多的资料.准备的过程虽然很烦很耗时间,不过因为需要查很多的资料, ...

随机推荐

  1. Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程

    上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑.on ...

  2. [转] Java中的访问控制

    可见/访问性 在同一类中 同一包中 不同包中  同一包子类中  不同包子类中   public  yes  yes  yes  yes  yes  protected   yes  yes  no   ...

  3. C++ XML 解释库

    rapidxml  http://rapidxml.sourceforge.net/index.htm

  4. Effective C++ 总结(三)

    五.实现  条款26:尽可能延后变量定义式的出现时间 如果你定义了一个变量且该类型带一个构造函数或析构函数,当程序到达该变量时,你要承受构造成本,而离开作用域时,你要承受析构成本.为了减少这个成本,最 ...

  5. DTD简单使用

    DTD:Document Type Definition DTD是一种简单的XML约束模式语言 DTD文档必须以utf-8或unicode编码 注释方式与HTML.XML文档相同 DTD文档的引用:紧 ...

  6. composer 说明<转>

    转自  http://blog.csdn.net/zzulp/article/details/18981029 Composer是一个基于项目的依赖管理器,负责将PHP项目所依赖的包或库安装到项目所在 ...

  7. C#学习第三天

    经过这几天的学习,真的有点觉得以前C学的太不好现在学C#也不顺畅,虽然很多东西都似曾相识,但是就是还得看好几遍才能记得住,而且现在都是简单的东西,还没有看到重载等稍微难点的地方.应该好好努力了,昨天忙 ...

  8. 刚入门的easyui

    这两天看了下easyui的教学先说说自己的一些小小理解吧! ----在使用easyui中也遇到了一个问题 : Uncaught TypeError:cannot call method ‘offset ...

  9. 封装对Cookie和Session设置或取值的类

    public class CookieHelper : System.Web.SessionState.IReadOnlySessionState    { public static void Se ...

  10. (转)ECSHOP给分类添加代表图

    转之--http://www.cnblogs.com/wangblognet/archive/2012/12/09/2809916.html ecshop的模板有很多不完善的地方,比如添加商品分类的时 ...