前言
SSE(Server-Sent Events)是一种服务器消息推送技术,是HTML5标准协议中的一部分,类似WebSocket,不同在于WebSocket可以双向通信,SSE只能服务器向浏览器发送消息。具体的规范可以查看 MDN。
简单使用
客户端,注意IE浏览器可能不支持
<script>
// 初始化, 参数为url
// 依赖H5
var sse = new EventSource("test");
sse.onmessage = function (e) {
console.log("message", e.data, e);
};
// 监听指定事件, (就不会进入onmessage了)
sse.addEventListener("me", function (e) {
console.log("me event", e.data);
});
</script>
服务器端,指定响应的 content-type 为 text/event-stream
@GetMapping(value = "/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public void test(HttpServletResponse response) throws IOException {
response.setContentType("text/event-stream");
response.setCharacterEncoding("utf-8");
// 指定事件标识
response.getWriter().write("event:me\n");
// ID
response.getWriter().write("id:" + UUID.randomUUID().toString() + "\n");
// 格式: data: + 数据 + 2个回车
response.getWriter().write("data:hello eventsource" + "\n\n");
response.getWriter().flush();
}
服务器连接中断,客户端会自动重连,默认超时重连时间为3秒。
Spring对SSE的支持
@GetMapping(value = "/test", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter test() throws IOException {
SseEmitter emitter = new SseEmitter();
SseEventBuilder builder = SseEmitter.event()
.name("me")
.id(UUID.randomUUID().toString())
.data("hello eventsource2");
emitter.send(builder);
emitter.complete();
return emitter;
}
方法返回值为SseEmitter,继承于ResponseBodyEmitter,SpringMVC中提供了ResponseBodyEmitterReturnValueHandler类来处理这种类型。
SpringBootAdmin(一个管理和监控SpringBoot应用的框架) 源码中就使用到了SSE。
参考
Server-Sent Events 教程
Server-Sent Events 的协议细节和实现
服务端推送技术 Server-sent Events 快速上手
详解Spring 5 Server-Sent Events(一) 基本介绍