Search code examples
springfluxspring-webfluxproject-reactorreactive

Spring WebFlux not streaming response


I was expecting this code to stream events to the client (code is in Kotlin but Java is very similar)

@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 is an iterable that generates a string on regular intervals. An infinite stream basically.

I don't see any output, it hangs forever.

I do see the string being printed on regular intervals (println(it)).

I am using the following curl:

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

Solution

  • Your error is here:

    flux.subscribe({println(it)})
    

    You subscribe to the Flux and consume it directly in the method. When this Flux reaches the Reactor Netty HTTP container, there is nothing to consume already.

    If you really would like println() each item, consider to use doOnNext() instead and really leave that subscribe() to the container.

    Also you have to really follow Server Side Events rules:

    The server-side event stream syntax is simple. Set the "Content-Type" header to "text/event-stream".

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

    So, when I do this:

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

    I start to get Server Side Events in my connected client:

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

    where at the same time I get logs on the server for the mentioned 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