如何生成随机字符串并使用 Mono 将其推出以每隔 X 秒或通过 Spring Reactive 随机延迟显示在浏览器中?

How to generate a random string and push it out using Mono to be displayed in a browser every X seconds or with random delay through Spring Reactive?

我希望浏览器在 API 使用 Spring Reactive Mono.

生成后立即在浏览器上显示随机生成的字符串

以下是我的示例程序,它可以生成随机字符串并每秒在浏览器上显示它,但页面不会加载任何新数据,看起来有点像静态数据加载。

@RestController
public class LogTailerController {

    @GetMapping(path = "/", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Mono<String> feed() {
        return Mono.just("foo-" + Math.random()).delayElement(Duration.ofSeconds(1));
    }

}

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

您可能需要查看 ConnectableFlux,它类似于 Flux,但专门设计用于连续发射元素。您可以创建一个 WebClient 对象,它默认通过其交换方法生成一个 Mono。然后,只需参考您在 LogRailerController class 中创建的路由来调用 feed 方法。

public void connectFeed() {

        ConnectableFlux<String> printEverySecond = WebClient.create("/") // Since your route is "/"
                .post()
                .body(...)
                .exchange() // produces a Mono object
                .flatMap(response -> response.bodyToMono(String.class)) // transformed into a Mono<String> 
                .flux() // now a Flux<String>
                .replay(Duration.of(1, ChronoUnit.SECONDS))
                .publish(); // now a ConnectableFlux<String>

        printEverySecond.subscribe();
        printEverySecond.connect();

}

除了使用 post().getBody()...flatMap(...),您还可以只使用 get(),并在 .exchange 之后立即调用 .bodyToMono(String.class)

这样做,您甚至可以将 feed() 逻辑放在 flatMap 中。这个策略的主要问题,以及当使用 @RestController 时,请求最终会超时,这在使用 RxNetty 时有点棘手。话虽如此,我建议有一个单独的组件 class 在重播 10 次后 returns 时调用 class,或者每 10 秒调用一次,或者以您认为最好的方式调用。与使用 @RestController 相比,此策略的优势恰恰在于可以从另一个 class 调用它,就像调用任何其他 bean 方法一样。

请注意,此处的所有主题都在 starter webflux 依赖项的范围内 - 我认为您不需要任何其他主题。