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. PHP安全编程:留心后门URL 直接可以通过URL访问(转)

    后门URL是指虽然无需直接调用的资源能直接通过URL访问.例如,下面WEB应用可能向登入用户显示敏感信息: <?php $authenticated = FALSE; $authenticate ...

  2. iOS教你轻松打造瀑布流Layout

    前言 : 在写这篇文章之前, 先祝贺自己, 属于我的GitHub终于来了. 这也是我的GitHub的第一份代码, 以下文章的代码均可以在Demo clone或下载. 欢迎大家给予意见. 觉得写得不错的 ...

  3. linux(centos)上配置nginx、mysql、php-fpm、redis开机启动<转>

    原文 http://levi.cg.am/archives/2925 I.nginx开机启动 在/etc/init.d/目录下创建脚本 1 vi  /etc/init.d/nginx 更改脚本权限 1 ...

  4. 如何开通www国际域名个人网站

    欢迎访问我的域名http://www.baiqiantao.xyz 一.准备知识 什么是域名? 所有以www开头的域名,就是国际域名:不以www开头的域名,都是为子域名. 域名都有后缀,后缀是有意义的 ...

  5. JAVA中的finalize()方法

    [转]JAVA中的finalize()方法 今天早上看Thinking in java的[第四章 初始化和清除].[  清除:终结和垃圾回收]的时候, 看到了这个东西. 用于清理滴... 当然,这个方 ...

  6. JavaScript Unicode字符操作

    charCodeAt() 方法 定义和用法charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数.方法 charCodeAt() 与 ...

  7. Linux filesystem structures.

    1. / – Root Every single file and directory starts from the root directory. Only root user has write ...

  8. 简单总结焦点事件、Event事件对象、冒泡事件

    每学习一些新的东西,要学会复习,总结和记录. 今天来简单总结一下学到的几个事件:焦点事件.Event事件对象.冒泡事件 其实这几个事件应该往深的说是挺难的,但今天主要是以一个小菜的角度去尝试理解一些基 ...

  9. 使用C++11 实现的线程池

    最近打算做一个服务器端程序,每来一个客户端请求新开一个线程进行处理.在网上查了一些资料后,准备使用线程池来做这个东西.使用C++11新的库处理想线程问题比以前简单了许多,在网上找到一份线程池的实现,h ...

  10. C++封装常用对象和对头文件探索

    在C++实际开发中,难免会使用到一些你极为常用的算法(比如笔者经常使用的多线程技术),实现这些算法的类或是全局函数或是命名空间等等经常都要被使用多次,你会有哪些办法来使用呢?笔者有4个办法. 第一个方 ...