如何生成随机字符串并使用 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 依赖项的范围内 - 我认为您不需要任何其他主题。
我希望浏览器在 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 依赖项的范围内 - 我认为您不需要任何其他主题。