'Spring Webflux - initial message without subscriber

I am trying to make an SSE Spring application, using Webflux. According to the documentation, the message is not sent to the sink if there is no subscriber. In my use case, I would like that the subscriber would receive the last message when calling for subscription. I have found that Sink can be configured in following way:

Sinks.many().replay().latest();

And when I have both publisher and subscriber, and the next subscriber calls for subscription, he receives the last sent message, which is great. However if I don't have any subscribers, publisher sends the message and then first subscriber comes in, it receives none. Which is just as documentation above says actually, but I am thinking how to solve that issue to meet my needs. As a workaround I did something like this:

if (shareSinks.currentSubscriberCount() == 0) {
  shareSinks.asFlux().subscribe();
}
shareSinks.tryEmitNext(shareDTO);

But subscribing the publisher to its own subscription doesn't sound like a clean way to do this...



Solution 1:[1]

This is a matter of hot and cold publishers. Currently, your publisher (Sinks.many().replay().latest()) is a cold publisher. Events that are being emitted while there is no subscriber, will just vanish.

What you need is a so called hot publisher. Hot publishers cache the events and a new subscriber will receive all previously cached events.

This will do the trick:

        final Sinks.Many<String> shareSinks = Sinks.many()
                .replay()
                .all(); // or .limit(10); to keep only the last 10 emissions

        final Flux<String> hotPublisher = shareSinks.asFlux()
                .cache(); // .cache() turns the cold flux into a 
                          // hot flux

        shareSinks.tryEmitNext("1");
        shareSinks.tryEmitNext("2");
        shareSinks.tryEmitNext("3");
        shareSinks.tryEmitNext("4");
        hotPublisher.subscribe(message -> System.out.println("received: " + message));

The console print out would be:

received: 1
received: 2
received: 3
received: 4

The Reactor docu also has a chapter on hot vs. cold.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1