Je suis nouveau dans la programmation réactive et Spring WebFlux. Je souhaite que mon application 1 publie l'événement Server Sent via Flux et mon application 2 l'écoute en continu.
Je souhaite que Flux publie à la demande (par exemple, lorsque quelque chose se produit). Tout l'exemple que j'ai trouvé est d'utiliser Flux.interval pour publier périodiquement un événement, et il ne semble pas possible d'ajouter/modifier le contenu dans Flux une fois qu'il est créé.
Comment puis-je atteindre mon objectif? Ou je me trompe totalement sur le plan conceptuel.
FluxProcessor
et FluxSink
L'une des techniques pour fournir manuellement des données à Flux
consiste à utiliser FluxProcessor#sink
méthode comme dans l'exemple suivant
@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());
}
}
Ici, j'ai créé DirectProcessor
afin de prendre en charge plusieurs abonnés, qui écouteront le flux de données. De plus, j'ai fourni FluxProcessor#serialize
qui fournit une prise en charge sûre du multiproducteur (invocation à partir de différents threads sans violation des règles de spécification des flux réactifs, en particulier règle 1. ). Enfin, en appelant " http: // localhost: 8080/send " nous verrons le message Hello World #1
(bien sûr, uniquement si vous vous êtes connecté à " http: // localhost: 808 " précédemment)
Juste une autre idée, en utilisant EmitterProcessor comme passerelle vers le flux
import reactor.core.publisher.EmitterProcessor;
import reactor.core.publisher.Flux;
public class MyEmitterProcessor {
EmitterProcessor<String> emitterProcessor;
public static void main(String args[]) {
MyEmitterProcessor myEmitterProcessor = new MyEmitterProcessor();
final Flux<String> publisher = myEmitterProcessor.getPubisher();
myEmitterProcessor.onNext("A");
myEmitterProcessor.onNext("B");
myEmitterProcessor.onNext("C");
myEmitterProcessor.complete();
publisher.subscribe(x -> System.out.println(x));
}
public Flux<String> getPublisher() {
emitterProcessor = EmitterProcessor.create();
return emitterProcessor.map(x -> "consume: " + x);
}
public void onNext(String nextString) {
emitterProcessor.onNext(nextString);
}
public void complete() {
emitterProcessor.onComplete();
}
}
Plus d'informations, voir ici dans la doc Reactor . Le document lui-même recommande que "la plupart du temps, vous devriez éviter d'utiliser un processeur. Ils sont plus difficiles à utiliser correctement et sujets à certains cas de coin. MAIS je ne sais pas quel genre de cas d'angle.