1. html5服务器发送事件(server-sent event)允许网页获得来自服务器的更新。
2. Server-Sent事件 - 单向消息传递
2.1. Server-Sent事件指的是网页自动获取来自服务器的更新。
2.2. 以前也可能做到这一点, 前提是网页不得不询问是否有可用的更新。通过服务器发送事件, 更新能够自动到达。
3. 浏览器支持: 所有主流浏览器均支持服务器发送事件, 除了Internet Explorer。
4. 接收Server-Sent事件通知
4.1. EventSource 对象用于接收服务器发送事件通知:
var es = new EventSource("http://localhost:8080/EventSource/SAR2C.action");
es.onmessage = function(messageEvent) {
document.getElementById("result").innerHTML += messageEvent.data + "<br />";
};
4.2. 创建一个新的EventSource对象, 然后规定发送更新的页面的URL(本例中是: "http://localhost:8080/EventSource/SAR2C.action"), 必须是全路径。
4.3. 每接收到一次更新, 就会发生onmessage事件。
4.4. 当onmessage事件发生时, 把已接收的数据推入id为"result"的元素中。
5. 检测Server-Sent事件支持
if(typeof(EventSource) !== "undefined") {
} else {
}
6. 服务器端代码实例
6.1. 为了让上面的例子可以运行, 您还需要能够发送数据更新的服务器(比如: Servlet、PHP和ASP)。
6.2. 新建一个名叫EventSource的动态Web工程

6.3. 编写ServerAutoRefresh2Client.java, 服务器端事件流的语法是非常简单的。把"Content-Type"报头设置为"text/event-stream"。现在, 您可以开始发送事件流了。
package com.lywgames.mysessionlistener;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServerAutoRefresh2Client extends HttpServlet {
private static final long serialVersionUID = 1L;
int id = 0;
long startTime = 0;
long endTime = 0;
int goodsCount = 9999;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String lastEventId = req.getHeader("Last-Event-ID");
startTime = endTime;
endTime = new Date().getTime();
System.out.println("lastEventId = " + lastEventId + ", 2次请求时间间隔:" + (endTime - startTime));
resp.setContentType("text/event-stream");
OutputStream os = new BufferedOutputStream(resp.getOutputStream());
// id,retry,data,之后必须使用两个\n\n(不然客户端取不到值)。
// id最好放在最前面。req.getHeader("Last-Event-ID"); 在谷歌、safari浏览器有值, 火狐浏览器为null。
os.write(("id:" + (++id) + "\n\n").getBytes());
// 声明浏览器在连接断开之后进行再次连接之前的等待时间 10秒
// 火狐浏览器默认5s请求一次, 谷歌浏览器默认3s请求一次, safari浏览器默认3s请求一次。
os.write(("retry:" + (10 * 1000) + "\n\n").getBytes());
os.write(("data:还有"+(goodsCount--)+"件商品。\n\n").getBytes());
os.flush();
os.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
6.4. EventSource.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>获得服务器更新</title>
</head>
<body>
商品数量:<div id="result"></div>
<script>
if(typeof(EventSource) !== "undefined") {
// 必须是全路径
var es = new EventSource("http://localhost:8080/EventSource/SAR2C.action");
es.onopen = function(event) {
}
es.onmessage = function(messageEvent) {
document.getElementById("result").innerHTML += messageEvent.data + "<br />";
};
es.onerror = function(event) {
};
} else {
document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持 server-sent 事件 ...";
}
</script>
</body>
</html>
6.5. 运行项目

7. EventSource 对象
7.1. 在上面的例子中, 我们使用onmessage事件来获取消息。不过还可以使用其他事件:

本文介绍了服务器发送事件(Server-Sent Event)技术,它允许网页从服务器自动获取更新,不再需要轮询。通过EventSource对象,浏览器可以监听来自服务器的事件流。示例代码展示了一个Servlet如何发送事件流,并在HTML页面上实时显示更新的商品数量。该技术在所有主流浏览器中得到支持,除了Internet Explorer。
5万+

被折叠的 条评论
为什么被折叠?



