Spring WebFlux 没有流式响应

Posted

技术标签:

【中文标题】Spring WebFlux 没有流式响应【英文标题】:Spring WebFlux not streaming response 【发布时间】:2018-11-22 04:07:48 【问题描述】:

我期待这段代码将事件流式传输到客户端(代码在 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 是一个迭代器,它定期生成一个字符串。基本上是无限流。

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

我确实看到定期打印字符串 (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】:

你的错误在这里:

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

【讨论】:

不幸的是,这也不起作用,我尝试使用 doOnNext() 并完全删除调用,但它不起作用,我没有得到任何响应。助焊剂是否需要以某种方式冲洗。调用阻塞并且不返回任何内容。 我已经通过一些进一步的调查更新了我的答案。 我有类似的问题,但仍然卡住。关心帮助? - ***.com/questions/63908428/…

以上是关于Spring WebFlux 没有流式响应的主要内容,如果未能解决你的问题,请参考以下文章

如何使 WebFilter 在非 WebFlux/非反应式 Spring Boot 应用程序中工作?

你的响应阻塞了没有?--Spring-WebFlux源码分析

Spring Webflux上传大图像文件并以流式方式使用WebClient发送文件[关闭]

自学Spring WebFlux

Spring Boot 自动配置的 Jackson ObjectMapper 默认不用于 WebFlux WebClient

spring5中的响应式编程框架webflux,到底是什么东西啊?