Java SpringWebClient和longpolling

Java SpringWebClient和longpolling,java,spring,project-reactor,Java,Spring,Project Reactor,我想使用Spring的反应式WebClient来轮询使用长轮询的REST端点 端点为聊天频道提供消息。当我呼叫它,但没有消息时,它会阻塞(即不返回),直到出现消息(或30秒过去) 因此,在一个同步的世界中,我会指定一个线程来监视这个通道,通过RestTemplate调用端点,等待结果,将其写入共享队列并启动下一个请求。然后,消费者可以对队列中出现的新项目做出反应 在被动的世界里,这有点不同。理想情况下,消费者会订阅大量的消息。问题是如何构建这种流量 逻辑应该是: Mono<String&g

我想使用Spring的反应式WebClient来轮询使用长轮询的REST端点

端点为聊天频道提供消息。当我呼叫它,但没有消息时,它会阻塞(即不返回),直到出现消息(或30秒过去)

因此,在一个同步的世界中,我会指定一个线程来监视这个通道,通过RestTemplate调用端点,等待结果,将其写入共享队列并启动下一个请求。然后,消费者可以对队列中出现的新项目做出反应

在被动的世界里,这有点不同。理想情况下,消费者会订阅大量的消息。问题是如何构建这种流量

逻辑应该是:

Mono<String> message = WebClient.get(). […] .bodyToMono(String.class);
// When the mono completes, create a new one just as described above
// Combine all of the monos into a Flux
flux.subscribe(message -> System.out.println("New message" + message);
Mono message=WebClient.get()。[…].bodytomino(String.class);
//当mono完成时,如上所述创建一个新的mono
//将所有monos组合成焊剂
flux.subscribe(message->System.out.println(“新消息”+消息);

我想我需要某种
开关…
运算符,但我可以找到正确的。

如果我得到了正确的答案,你应该可以通过类似的方法来解决这个问题

Flux.interval(Duration.ofSeconds(30))
    .flatMap(counter -> WebClient.get().[…].bodyToMono(String.class))
    .subscribe(message -> System.out.println("New message" + message))
正如@123所指出的:

您可以只使用repeat,即
WebClient.get().[…].bodytomino(String.class).repeat()
,它将为您提供一系列回复,并且只在完成上一个回复后才开始下一个回复

实际上,这里需要的是
defer()
repeat()
defer()
接受Monos的供应商,并且
repeat()
将在完成之前的订阅后重新订阅Mono。这将导致再次调用供应商,从而启动新的http请求

此外,由于这会永远运行,因此会导致不干净的应用程序关闭:如果发生关闭,可能会有一个http请求正在运行。为了彻底结束流量,可以使用另一个发布服务器(如
EmitterProcessor
)来使用
takentilother()
)。然后,在
@PreDestroy
方法中,可以调用
shutdown.onNext(true)
,这将导致取消http请求

我的解决方案现在如下所示:

   Mono.defer(() -> receiveMessage())
   .repeat()
   .takeUntilOther(shutdown)
   .subscribe(message -> System.out.println("New message" + message);

您只需使用
repeat
,即
WebClient.get().[…]bodytomino(String.class).repeat()
,将给你们一系列的回复,并且只有在上一个回复完成后才会开始下一个回复。@123是的,就是这样!你们介意写一个答案让我接受吗?在电话上,你们可以自己发布,谢谢你们的回答。不幸的是,这只适用于实际的轮询,而不适用于阻塞请求的长时间轮询。啊明白了,谢谢你的回复。