Pét*_*res 5 java event-stream quarkus vert.x-webclient mutiny
更新!
在解决了一些与主要问题无关的问题后,我修复了示例代码中的小错误,主要问题仍然是关于服务之间的非阻塞流。
背景资料:
我正在 Quarkus 下移植 Spring WebFlux 服务。该服务对多个庞大数据集运行长时间搜索,并在可用时以 Flux(文本/事件流)形式返回部分结果。
问题:
现在,我尝试在 Quarkus 下将 Mutiny Multi 与 Vert.x 结合使用,但无法弄清楚消费者服务如何在不阻塞的情况下接收此流。
在所有示例中,消费者要么是 JS 前端页面,要么生产者的内容类型是 application/json,在将其发送到一个 JSON 对象之前,它似乎会一直阻塞,直到 Multi 完成(这在我的应用程序中没有任何意义)。
问题:
这是一个简化的例子
测试实体
public class SearchResult implements Serializable {
    private String content;
    public SearchResult(String content) {
        this.content = content;
    }
    //.. toString, getters and setters
    
}
生产者 1. 简单的无限流 -> 挂起
@GET
@Path("/search")
@Produces(MediaType.SERVER_SENT_EVENTS)
@SseElementType(MediaType.APPLICATION_JSON)
public Multi<SearchResult> getResults() {
        return Multi.createFrom().ticks().every(Duration.ofSeconds(2)              .onItem().transform(n -> new SearchResult(n.toString()));
}
生产者 2. 具有 Vertx Paths 无限流 -> 挂起
@Route(path = "/routed", methods = HttpMethod.GET)
public Multi<SearchResult> getSrStreamRouted(RoutingContext context) {
        log.info("routed run");
        return ReactiveRoutes.asEventStream(Multi.createFrom().ticks().every(Duration.ofSeconds(2))
                .onItem().transform(n -> new SearchResult(n.toString()));
}
生产者 3. 简单有限流 -> 阻塞直至完成
@GET
@Path("/search")
@Produces(MediaType.SERVER_SENT_EVENTS)
@SseElementType(MediaType.APPLICATION_JSON)
public Multi<SearchResult> getResults() {
    return Multi.createFrom().ticks().every(Duration.ofSeconds(2))
        .transform().byTakingFirstItems(5)
        .onItem().transform(n -> new SearchResult(n.toString()));
}
消费者:
在生产者和消费者端尝试了多种不同的解决方案,但在每种情况下,流都会阻塞直到完成或无限期挂起,而不会为无限流传输数据。我用 httpie 得到了相同的结果。这是最新的迭代:
WebClientOptions webClientOptions = new WebClientOptions().setDefaultHost("localhost").setDefaultPort(8182);
WebClient client = WebClient.create(vertx, webClientOptions);
        
client.get("/string")
                .send()
                .onFailure().invoke(resp -> log.error("error: " + resp))
                .onItem().invoke(resp -> log.info("result: " + resp.statusCode()))
                .toMulti()
                .subscribe().with(r -> log.info(String.format("Subscribe: code:%d body:%s",r.statusCode(), r.bodyAsString())));
小智 5
Vert.x Web 客户端无法与 SSE 配合使用(无需配置)。来自https://vertx.io/docs/vertx-web-client/java/:
响应被完全缓冲,使用 BodyCodec.pipe 将响应通过管道传输到写入流
它会等待直到响应完成。您可以使用原始Vert.x HTTP 客户端或使用pipe编解码器。https://vertx.io/docs/vertx-web-client/java/#_decoding_responses上给出了示例。
或者,您可以使用 SSE 客户端,例如:https: //github.com/quarkusio/quarkus-quickstarts/blob/master/kafka-quickstart/src/test/java/org/acme/kafka/PriceResourceTest.java# L27-L34
| 归档时间: | 
 | 
| 查看次数: | 1798 次 | 
| 最近记录: |