Spring Boot 中实现服务端主动数据推送
0x9C40
January 5th, 2022

在日常开发中通常使用 WebSocket 实现服务端的主动地数据推送,这里简单介绍两种其他的数据推送方案,ndjsonSSE

ndjson

ndjson 全称 Newline Delimited JSON,即使用换行符分割的 JSON,同时能够保证每一行的内容都是一个完整的 JSON。这里使用 ndjson 并不是因为它可以实现服务端数据推送,而是凭借 ndjson 的数据格式的特性,作为服务端的 JSON 数据流的数据输出,来更好地帮助我们实现数据推送的效果。

这里使用 Spring Boot 作为基础的服务端框架,简单演示一下相关代码及功能。首先要确保项目依赖中包含 spring-boot-starter-webflux 依赖包。

代码示例

@GetMapping(value = "ndjson", produces = MediaType.APPLICATION_NDJSON_VALUE)
Flux<Data> ndjson() {
    return dataStream();
}

private Flux<Data> dataStream() {
    return Flux.interval(Duration.ofSeconds(1))
            .take(5)
            .map(i -> new Data(i, Instant.now()));
}

代码中定义了一个私有方法用来生成数据流,效果是每隔 1 秒生成一条数据。在 @GetMapping中指定了 MediaType.APPLICATION_NDJSON_VALUE 作为数据的响应格式。

SSE

SSE 全称 Server-sent events,即服务器发送事件,服务端可使用 SSE 生成相应的数据流。

代码示例,同样需要 WebFlux 支持。

@GetMapping(value = "sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
Flux<Data> sse() {
    return dataStream();
}

private Flux<Data> dataStream() {
   return Flux.interval(Duration.ofSeconds(1))
            .take(5)
            .map(i -> new Data(i, Instant.now()));
}

ndjson 方案唯一的不同是,数据响应的格式替换为了MediaType.TEXT_EVENT_STREAM_VALUE

总结

虽然 ndjsonSSE 方案都可以实现服务端的数据推送,但这两种的数据通信都是单向通信,只能从服务端到客户端,无法实现双向通信,需要根据自身的场景需要酌情考虑使用。

项目的完整代码可参考 StreamJsonController

参考内容

Arweave TX
_dWoA7WctDr394uABeDoYiKlcVuf6QlQ_IcC5QVn7SE
Ethereum Address
0x9C401508CA280B709C5d5178C2d94701fdAb57A1
Content Digest
jKZQt8upDGpbg89cD9KCJAXCvip-FJrgmpyexQLB_bY