Spring WebFlux没有流媒体响应

时间:2018-06-12 17:23:42

标签: spring flux spring-webflux project-reactor reactive

我期待这段代码将事件传递给客户端(代码在Kotlin中,但Java非常相似)

@RestController
object CustomerController {
    @GetMapping("/load", produces = arrayOf("application/stream+json"))
    fun load(): Flux<String> {
        var flux = Flux.fromIterable(ResultIterable())
        flux.subscribe({println(it)})
        return flux
    }
}

ResultIterable是一个可定期生成字符串的iterable。基本上是一个无限的流。

我没有看到任何输出,它会永远挂起。

我确实看到字符串定期打印(println(it))。

我使用以下卷曲:

curl -X GET   http://localhost:8080/load   -H 'accept: application/stream+json'   -H 'cache-control: no-cache'   -H 'content-type: application/stream+json'

1 个答案:

答案 0 :(得分:7)

您的错误在这里:

flux.subscribe({println(it)})

您订阅Flux并直接在方法中使用它。 当此Flux到达Reactor Netty HTTP容器时,没有任何东西可以使用。

如果您真的希望println()每个项目,请考虑使用doOnNext()代替,并将subscribe()留给容器。

此外,您必须遵循服务器端事件规则:

  

服务器端事件流语法很简单。将“Content-Type”标题设置为“text / event-stream”。

https://www.w3schools.com/html/html5_serversentevents.asp

所以,当我这样做时:

@GetMapping("/load", produces = [MediaType.TEXT_EVENT_STREAM_VALUE])
fun load() =
        Flux.just("foo", "bar", "baz")
                .doOnNext({ println(it) })

我开始在我的连接客户端中获取服务器端事件:

C:\tmp\so50823339>curl -X GET   http://localhost:8080/load
data:foo

data:bar

data:baz


C:\tmp\so50823339>

同时我在服务器上获取上述doOnNext()

的日志
2018-06-12 17:33:37.453  INFO 6800 --- [           main] c.e.s.s.So50823339ApplicationKt          : Started So50823339ApplicationKt in 3.112 seconds (JVM running for 3.924)
foo
bar
baz