Server-Sent Events入门

前言

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(一) 基本介绍

posted @ 2021-07-25 01:55  strongmore  阅读(1056)  评论(0编辑  收藏  举报