SSE协议介绍

SSE协议的全称是Server-Send Events,专门用于服务端实时推送消息。

SSE是基于HTTP协议,通过长连接的方式持续获取消息。也就是客户端建立TCP链接后,向服务端发起一个HTTP请求,服务端接收到请求后把要返回的内容,按照事件流的方式,不断推送给客户端。跟下载文件一样,所有内容推送完了,连接才关闭。

SSE协议本质上是对HTTP返回的内容进行了约定,客户端按照约定进行解析。

协议的优缺点

SSE协议和websocket协议都可以用作服务端推送,相对于websocket协议的优势有:

  1. 基于http协议,主流浏览器都支持
  2. 轻量级协议
  3. 可以定制消息类型
  4. 支持超时重连

也有一些不足:

  1. 服务端单向推送消息,不是全双工可以双向通信
  2. 协议不支持二进制传输,需要使用方把现在转成二进制格式

协议格式

协议头

SSE协议返回的是事件流,需要指定内容类型。并且,协议是长连接,也要开启长连接和禁止缓存内容。所以要在HTTP header里加上这3个信息:

  1. Content-Type:text/event-stream
  2. Connection:keep-alive
  3. Cache-Control:no-cache

协议内容

协议内容放在http返回的body里,每次返回一个Event信息。每个Event里可以包含5个属性:

  1. id
  2. event
  3. data
  4. retry
  5. :(注释消息)

每个属性值占用一行,每行的内容都是由属性名称+属性值组成+换行符,之间用冒号隔开(:)。连个消息之间用额外的换行符区分。

// 这是服务端返回的两条消息
id:1
data:你
data:好,

id:2
event: question
data:你的
data:名字叫什么?

属性介绍

id字段

id用于表示Event的序号,客户端通过序号实现断线重连功能。需要重连的时候,客户端在HTTP的header里加一个Last-Event-ID字段,把最后接收到的id传给服务端。服务端实现了重连功能,就能继续传Last-Event-ID之后的消息给客户端。

event字段

event表示自定义事件类型,客户端通过该字段区分不同消息。

id:2
event: question
data:你的
data:名字叫什么?

data字段

data表示返回的业务数据,如果数据很长可以分成多行返回。

id:1
data:你
data:好,

retry字段

retry表示重连的间隔,以毫秒为单位。

id:1
retry:30000
data:你
data:好,

:(注释消息)

需要返回注释消息的时候,格式是以冒号开头,后面接注释信息

id:1
data:你
data:好,
:这是注释信息

Spring实现SSE接口

spring webmvc已经支持了SSE协议,要返回这是一个简单的SSE接口示例,会返回3条消息:

@GetMapping(value = "/sse")
public SseEmitter sse(HttpServletResponse response) {
    response.setCharacterEncoding("UTF-8");

    SseEmitter sseEmitter = new SseEmitter();
    sseEmitter.onCompletion(() -> System.out.println("complete"));

    new Thread(() -> {
        for (int i = 1; i <= 3; i++) {
            try {
                Set<ResponseBodyEmitter.DataWithMediaType> body = SseEmitter.event()
                        .id(String.valueOf(i))
                        .name("custom-" + i)
                        .data("你好:" + i)
												.data("我叫AA" + i)
                        .comment("这是注释内容")
                        .reconnectTime(5000)
                        .build();
                sseEmitter.send(body);
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 断开连接
        sseEmitter.complete();
    }).start();
    return sseEmitter;
}

这里做了几件事:

  1. 通过SseEmitter对象返回事件流,这是时会在响应头里自动加上Content-Type: text/event-stream、Connection: keep-alive信息
  2. 事件流结束后调用sseEmitter.complete()关闭连接
  3. 使用onCompletion方法监听连接关闭消息
  4. 通过HttpServletResponse来设置返回的编码为UTF-8,最终返回的header是Content-Type: text/event-stream;charset=UTF-8

相关推荐

  1. SSE协议介绍

    2024-03-14 22:12:02       47 阅读
  2. <span style='color:red;'>SSH</span><span style='color:red;'>协议</span>

    SSH协议

    2024-03-14 22:12:02      23 阅读
  3. <span style='color:red;'>ssh</span><span style='color:red;'>介绍</span>

    ssh介绍

    2024-03-14 22:12:02      35 阅读
  4. SSL/TLS协议

    2024-03-14 22:12:02       38 阅读
  5. SSL/TLS 协议

    2024-03-14 22:12:02       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-14 22:12:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-14 22:12:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-03-14 22:12:02       82 阅读
  4. Python语言-面向对象

    2024-03-14 22:12:02       91 阅读

热门阅读

  1. 2024.3.13每日一题

    2024-03-14 22:12:02       38 阅读
  2. 04 数据结构之队列

    2024-03-14 22:12:02       41 阅读
  3. STM32day2

    STM32day2

    2024-03-14 22:12:02      35 阅读
  4. adb 筛选查看Unity日志

    2024-03-14 22:12:02       37 阅读
  5. 前端面试练习24.3.12

    2024-03-14 22:12:02       37 阅读
  6. Android 二维码相关(二)

    2024-03-14 22:12:02       45 阅读