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'
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