Vert.x HttpClient/WebClient如何逐块/流式处理响应 替代AsyncHttpClient方案
解答
这个需求完全可以实现,Vert.x WebClient原生支持流式逐块处理响应,能力和AsyncHttpClient的AsyncHandler完全对齐,不需要把响应全量加载到内存再处理。
最简实现方式
不用搞复杂的自定义BodyCodec,直接监听响应流即可,核心是调用bodyAsStream()拿到响应的可读流,直接注册片段处理器:
// 初始化WebClient WebClient webClient = WebClient.create(vertx); webClient.get(yourPort, yourHost, yourPath) .send() .onSuccess(resp -> { if (resp.statusCode() == 200) { // 拿到响应字节流 ReadStream<Buffer> respStream = resp.bodyAsStream(); // 逐块处理响应片段,每收到一小段就触发一次 respStream.handler(chunk -> { // 这里写你的片段处理逻辑,chunk就是当前收到的字节片段 doYourChunkProcess(chunk); }); // 所有片段处理完成的回调 respStream.endHandler(v -> { doAfterAllProcessed(); }); // 流处理异常回调 respStream.exceptionHandler(e -> { handleStreamError(e); }); } }) .onFailure(e -> { // 请求发送失败的处理逻辑 handleRequestError(e); });
自定义BodyCodec的数据流逻辑说明
如果你需要适配现有封装逻辑,必须用BodyCodec实现的话,核心逻辑也很容易理解:
- 自定义BodyCodec的
createWriteStream()方法要求你返回一个WriteStream实例,Vert.x会把响应的ReadStream自动和你返回的WriteStream做对接 - 你只需要自己实现
WriteStream的write(Buffer chunk)方法,每收到一个响应片段,Vert.x就会调用一次这个write方法,你在方法里处理片段即可,和上面直接给ReadStream注册handler的效果完全一致 - 基础场景下不需要你处理背压、流控逻辑,Vert.x底层已经做了默认适配,只有特殊的流控需求才需要额外实现对应的方法
与AsyncHandler的能力对应
你可以完全按之前AsyncHandler的逻辑做迁移,对应关系如下:
AsyncHandler#onStatusReceived、AsyncHandler#onHeadersReceived→ 对应send成功回调里直接取resp.statusCode()、resp.headers()AsyncHandler#onBodyPartReceived→ 对应ReadStream#handler的回调参数,或者自定义WriteStream的write方法参数AsyncHandler#onCompleted→ 对应ReadStream#endHandlerAsyncHandler#onThrowable→ 对应ReadStream#exceptionHandler+send的onFailure回调
内容的提问来源于stack exchange,提问作者Igor Fedorov
相关产品推荐
相关产品推荐

