Spring MVC SSE-服务端推送技术
Web 项目中,浏览器与服务器是通过请求和响应来实现功能功能交互的,当服务端出现新的信息需要让前端知道时,就需要用到服务器推送技术。
服务端推送技术有基于SSE
(Server Send Event 服务端发送事件)的服务器端推送,该方式需要浏览器支持,而目前主流浏览器最近版本基本都支持;基于Servlet 3.0+
的异步方法特性;WebSocket
双向通信技术。
SSE
SSE
(Server Send Event) 是 HTML 5 规范中的一部分。
该技术主要由两个部分组成:第一个部分是服务器端与浏览器端之间的通讯协议,第二部分则是在浏览器端可供 JavaScript
使用的 EventSource
对象。通讯协议是基于纯文本的简单协议。服务器端的响应的内容类型是“text/event-stream
”。
响应文本的内容可以看成是一个事件流,由不同的事件所组成。每个事件由类型和数据两部分组成,同时每个事件可以有一个可选的标识符。不同事件的内容之间通过仅包含回车符和换行符的空行(\r\n)来分隔。
示例代码
- Controller
服务端SSE支持的输出媒体类型为text/event-stream
。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46package com.controller;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 服务器端推送技术SSE(Server Send Event)
* 输出的媒体类型:produces = "text/event-stream;charset=UTF-8"
* 注意要添加返回消息的编码:charset=UTF-8
* @author Rocky
*
*/
public class SseController {
public String sseV() {
return "sse";
}
public String push(HttpServletResponse response) throws UnsupportedEncodingException {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
Random random = new Random();
try {
//每间隔5秒执行一次,奇怪的是目前测的是会延次3秒,即设的是5秒,但间隔的是8秒
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "data:当前时间: " + sdf.format(new Date()) + "\n\n";
}
} - sse.jsp
EventSource 对象只有新式的浏览器才支持, 是 SSE的客户端。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/jquery-1.11.0.js"></script>
<!-- <script type="text/javascript" src="/static/js/jquery-1.11.0.js"></script> -->
<script type="text/javascript">
//EventSource对象需要浏览器支持
if(!!window.EventSource){
var source = new EventSource('push');
s = '';
//事件监听器,获取服务器推送的消息
source.addEventListener('message',function(e){
s+=e.data + "<br/>";
$("#msgFromPush").html(s);
});
source.addEventListener('open',function(e){
console.log("连接打开.");
}, false);
source.addEventListener('error',function(e){
if(e.readyState == EventSource.CLOSED){
console.log("连接关闭");
}else{
console.log(e.readyState);
}
}, false);
}else{
console.log("你的浏览器不支持SSE");
}
</script>
<title>SSE Demo</title>
</head>
<body>
<div id="msgFromPush"></div>
</body>
</html>
参考
SSE技术详解:一种全新的HTML5服务器推送事件技术
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
Spring MVC SSE-服务端推送技术