1

我希望浏览器在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>
4

1 回答 1

1

您可能想查看ConnectableFlux,它类似于Flux,但专门设计用于连续发射元素。您可以创建一个WebClient对象,该对象默认通过其交换方法生成一个 Mono。然后,只需参考您在 LogRailerController 类中创建的路由即可调用 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(),然后在 ..bodyToMono(String.class)之后立即调用.exchange

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

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

于 2019-09-25T00:59:15.407 回答