Java SpringWebClient和longpolling
我想使用Spring的反应式WebClient来轮询使用长轮询的REST端点 端点为聊天频道提供消息。当我呼叫它,但没有消息时,它会阻塞(即不返回),直到出现消息(或30秒过去) 因此,在一个同步的世界中,我会指定一个线程来监视这个通道,通过RestTemplate调用端点,等待结果,将其写入共享队列并启动下一个请求。然后,消费者可以对队列中出现的新项目做出反应 在被动的世界里,这有点不同。理想情况下,消费者会订阅大量的消息。问题是如何构建这种流量 逻辑应该是:Java SpringWebClient和longpolling,java,spring,project-reactor,Java,Spring,Project Reactor,我想使用Spring的反应式WebClient来轮询使用长轮询的REST端点 端点为聊天频道提供消息。当我呼叫它,但没有消息时,它会阻塞(即不返回),直到出现消息(或30秒过去) 因此,在一个同步的世界中,我会指定一个线程来监视这个通道,通过RestTemplate调用端点,等待结果,将其写入共享队列并启动下一个请求。然后,消费者可以对队列中出现的新项目做出反应 在被动的世界里,这有点不同。理想情况下,消费者会订阅大量的消息。问题是如何构建这种流量 逻辑应该是: Mono<String&g
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是的,就是这样!你们介意写一个答案让我接受吗?在电话上,你们可以自己发布,谢谢你们的回答。不幸的是,这只适用于实际的轮询,而不适用于阻塞请求的长时间轮询。啊明白了,谢谢你的回复。