我有一个简单的用例。这是进行休息调用,查询mongo然后将任意大量的数据流返回给客户端,所有这些都使用反应流类型进行背压管理。
使用Spring WebFlux和Reactor很容易实现。我现在正尝试使用vert.x实现相同的目标,作为实现简易性的比较。
发现vert.x mongo客户端缺乏管理背压的支持,我现在尝试使用WebFlux mongo客户端,然后通过vert.x HttpResponse将数据泵回,如下面的代码所示:
public class MyMongoVerticle extends AbstractVerticle {
ReactiveMongoOperations operations;
public void start() throws Exception {
final Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.get("/myUrl").handler(ctx -> {
// WebFlux mongo operations returns a ReactiveStreams compatible entity
Flux<Document> mongoStream = operations.findAll(Document.class, "myCollection");
ReactiveReadStream rrs = ReactiveReadStream.readStream();
// rrs is ReactiveStream streams subscriber
mongoStream.subscribe(rrs);
// Pump pumps the rrs (ReactiveReadStream) to the HttpServerResponse (ReactiveWriteStream)
Pump pump = Pump.pump(rrs, ctx.response());
pump.start();
});
vertx.createHttpServer().requestHandler(router::accept).listen(8777);
}
}
我遇到的问题是HttpServerResponse实现了ReactiveWriteStream&lt; Buffer&gt;所以期待缓冲而不是文档流。结果是ClassCaseException。
我的问题是如何将此文档流转换为ReactiveWriteStream&lt; Buffer&gt;?可能有另一种更好的方法可以做到这一点,所以我对其他如何实现这一点的建议持开放态度。
答案 0 :(得分:0)
Pump
不会为你工作,因为它目前不支持转换。你必须自己实施泵。幸运的是,这不应该太难:
Flux<Document> mongoStream = operations.findAll(Document.class, "myCollection");
ReactiveReadStream<Document> rrs = ReactiveReadStream.readStream();
mongoStream.subscribe(rrs);
HttpServerResponse outStream = ctx.response();
// Changes start here
rrs.handler(d -> {
if (outStream.writeQueueFull()) {
outStream.drainHandler((s) -> {
rrs.resume();
});
rrs.pause();
}
else {
outStream.write(d.toJson());
}
}).endHandler(h -> {
outStream.end();
});
请注意,我不希望这比#34; native&#34;更有效。 WebFlux实施。
此外,此示例中的JSON将被破坏,因为我没有将其包装在适当的JSON数组中