首页 文章

Spring WebFlux没有流媒体响应

提问于
浏览
1

我期待这段代码将事件传递给客户端(代码在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 回答

  • 4

    你的错误在这里:

    flux.subscribe({println(it)})
    

    您订阅 Flux 并直接在方法中使用它 . 当 Flux 到达Reactor Netty HTTP容器时,没有什么可以消耗的 .

    如果你真的想要 println() 每个项目,请考虑使用 doOnNext() 而不是将 subscribe() 留给容器 .

    您还必须遵循服务器端事件规则:

    服务器端事件流语法很简单 . 将“Content-Type” Headers 设置为“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
    

相关问题