#java #spring #spring-mvc #reactive-programming #spring-webflux
#java #spring #spring-mvc #реактивное программирование #spring-webflux
Вопрос:
У меня есть приложение для чата с spring reactive webflux. Когда создается новое сообщение, все подписчики получают это сообщение (это просто пример для упрощения моей проблемы). Все правильно и работало безукоризненно. Но теперь мне нужно событие для подписчиков при поступлении нового сообщения.
Это мой код:
Контроллер:
@Autowired
@Qualifier("ptpReplayProcessor")
private ReplayProcessor<String> ptpReplayProcessor;
@GetMapping(value = "/chat/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> subscribe() {
return Flux.from(ptpReplayProcessor);
}
ReplayProcessorConfig:
@Configuration
public class ReplayProcessorConfig {
@Bean("ptpReplayProcessor")
ReplayProcessor<String> ptpReplayProcessor() {
ReplayProcessor<String> replayProcessor = ReplayProcessor.create(0, false);
replayProcessor.subscribe(new BaseSubscriber<String>() {
@Override
protected void hookOnNext(String ptp) {
System.out.println("replay processor called!");
}
});
return replayProcessor;
}
}
pom.xml
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
Когда создается новое сообщение, я вызываю ptpReplayProcessor.onNext(message)
. Это работает правильно, и все клиенты получают сообщение, но фраза replay processor called!
просто выводится от отправителя сообщения. Я хочу вызвать событие для всех клиентов при получении нового сообщения. Также я пробовал методы ReplayProcessor.doOnNext()
и ReplayProcessor.doOnEach()
, но не сработало. Есть ли какой-либо способ сделать это?
Комментарии:
1. Что вы подразумеваете под «Я хочу вызвать событие для всех клиентов» ?
2. Мне нужно что-то сделать для клиентов в серверной части (предположим, выполнить некоторую проверку или для ведения журнала), когда пришло новое сообщение.
3. Они уже получают сообщение. Зачем вам нужно дополнительное событие?
4. Клиенты получают сообщения на стороне клиента , но я хочу событие на стороне сервера.
5. Итак, если у вас есть 5 клиентов, вы хотите, чтобы на стороне сервера было инициировано 5 событий для каждого сообщения?
Ответ №1:
вы можете сделать это в своем методе подписки:
return Flux.from(ptpReplayProcessor).doOnNext(s -> System.out.println("new message has been sent"));
Комментарии:
1.
doOnNext
предназначено только для отправителя сообщения, а не для получателей. Я указал в своем вопросе, что это событие не сработало.2. В вашем сценарии вы добавляли событие onNext в процессоре воспроизведения. таким образом, событие запускалось только тогда, когда процессор воспроизведения получал сообщение для отправки. в моем случае я добавил событие onNext в flux, которое отвечает за отправку сообщений конкретному пользователю, поэтому оно будет запускаться для каждого сообщения для каждого пользователя. таким образом, вы можете эффективно сказать, что клиент получил сообщение. если вы хотите быть уверены, что сообщение было доставлено правильно, нет способа решить это только на стороне сервера. на стороне клиента также обязательно какое-либо подтверждение.