【问题标题】:How to use AsyncHttpClient to send multiple HTTP calls asynchronously?如何使用 AsyncHttpClient 异步发送多个 HTTP 调用?
【发布时间】:2022-10-15 11:24:54
【问题描述】:

我正在使用 https://github.com/AsyncHttpClient/async-http-client 发送异步 POST 请求。

例子:

try {
        CompletableFuture<org.asynchttpclient.Response> whenResponse = asyncHttpClient()
            .preparePost("https://some-site.com/v1/subscription1")
            .setHeader("Content-Type","application/json")
            .setHeader("Accept", "application/json")
            .setBody(getData())
            .execute()
            .toCompletableFuture()
            .exceptionally(t -> {
              // handle error
            })
            .thenApply(
                response -> { return response; }
            );
        return whenResponse.join();
    } catch (Exception e) {
        // handle error
    }

是否可以重构它以异步将相同的数据/正文发送到多个 URL?

最好概述最有效的方法(此处可以避免循环)?

【问题讨论】:

  • @AlexR 看起来 allOf() 会起作用。但我不确定如何在一个循环中实现多个 asyncHttpClient() 。你能举个例子吗?

标签: java asynchttpclient


【解决方案1】:

首先,在使用asyncHttpClient() 时,您应该记住在发送完请求后关闭该方法返回的AsyncHttpClient。或者,您可以在全局范围内定义一个 AsyncHttpClient 实例并将其重用于您的所有请求。

由于您评论 CompletableFuture.allOf() 确实为您工作,我假设您对请求返回的结果不感兴趣。如果您是,您的方法可以返回一个单独的CompletableFuture 实例列表,您可以在对allOf() 创建的实例调用join() 后安全地检查这些实例。然后必须将这个join 调用移到该方法中。

除非您想对 URL 进行硬编码,否则显然无法避免循环,在这种情况下,您必须展开循环并手动创建传递给 allOf 的数组。

以下是如何实施解决方案的示例:

import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.Response;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

import static org.asynchttpclient.Dsl.*;

public final class Example {
    public static final AsyncHttpClient ASYNC_HTTP_CLIENT = asyncHttpClient();

    public static void main(String[] args) throws IOException {
        List<String> urls = List.of(
                "https://some-site.com/v1/subscription1",
                "https://some-site.com/v1/subscription2"
                // etc.
        );
        CompletableFuture<Void> requests = sendRequests(urls);
        requests.join();

        ASYNC_HTTP_CLIENT.close();
    }

    public static CompletableFuture<Void> sendRequests(List<String> urls) {
        Stream<CompletableFuture<Response>> stream = urls.stream()
                .map(url -> ASYNC_HTTP_CLIENT.preparePost(url)
                        .setHeader("Content-Type", "application/json")
                        .setHeader("Accept", "application/json")
                        .setBody(getData())
                        .execute()
                        .toCompletableFuture());
        return CompletableFuture.allOf(stream.toArray(CompletableFuture[]::new));
    }

    private static byte[] getData() {return new byte[0]; /* return actual data */}
}

【讨论】:

    猜你喜欢
    • 2016-09-04
    • 1970-01-01
    • 2015-08-12
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 2016-11-15
    相关资源
    最近更新 更多