I am new to Reactive programming and Spring WebFlux. I want to make my App 1 publish Server Sent event through Flux and my App 2 listen on it continuously.
I want Flux publish on-demand (e.g. when something happens). All the example I found is to use Flux.interval to periodically publish event, and there seems no way to append/modify the content in Flux once it is created.
How can I achieve my goal? Or I am totally wrong conceptually.
Publish "dynamically" using FluxProcessor
and FluxSink
One of the techniques to supply data manually to the Flux
is using FluxProcessor#sink
method as in the following example
@SpringBootApplication @RestController public class DemoApplication { final FluxProcessor processor; final FluxSink sink; final AtomicLong counter; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } public DemoApplication() { this.processor = DirectProcessor.create().serialize(); this.sink = processor.sink(); this.counter = new AtomicLong(); } @GetMapping("/send") public void test() { sink.next("Hello World #" + counter.getAndIncrement()); } @RequestMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE) public Flux<ServerSentEvent> sse() { return processor.map(e -> ServerSentEvent.builder(e).build()); } }
Here, I created DirectProcessor
in order to support multiple subscribers, that will listen to the data stream. Also, I provided additional FluxProcessor#serialize
which provide safe support for multiproducer (invocation from different threads without violation of Reactive Streams spec rules, especially rule 1.3). Finally, by calling "http://localhost:8080/send" we will see the message Hello World #1
(of course, only in case if you connected to the "http://localhost:8080" previously)