gpt4 book ai didi

java - 如何使用 Apache HttpClient 获得持久的 HttpConnection?

转载 作者:行者123 更新时间:2023-11-29 08:33:20 26 4
gpt4 key购买 nike

在我的测试应用程序中,我向具有 Apache HttpClient 的同一主机执行连续的 HttpGet 请求,但在每次下一个请求时,结果表明前一个 HttpConnection 已关闭,新的 HttpConnection HttpConnection 已创建。

我使用相同的 HttpClient 实例并且不关闭响应。我从每个实体中获取 InputStream,使用 Scanner 从中读取,然后关闭 Scanner。我已经测试了 KeepAliveStrategy,它返回 true。请求之间的时间不超过 keepAlive 或 connectionTimeToLive 持续时间。

谁能告诉我这种行为的原因是什么?

已更新

我找到了解决方案。为了使 HttpConnecton 保持 Activity 状态,有必要在构建 HttpClient 时设置 HttpClientConnectionManager。我使用过 BasicHttpClientConnectionManager

ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context)
{
long keepAlive = super.getKeepAliveDuration(response, context);
if (keepAlive == -1)
keepAlive = 120000;
return keepAlive;
}
};
HttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager();
try (CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager) // without this setting connection is not kept alive
.setDefaultCookieStore(store)
.setKeepAliveStrategy(keepAliveStrat)
.setConnectionTimeToLive(120, TimeUnit.SECONDS)
.setUserAgent(USER_AGENT)
.build())
{
HttpClientContext context = new HttpClientContext();
RequestConfig config = RequestConfig.custom()
.setCookieSpec(CookieSpecs.DEFAULT)
.setSocketTimeout(10000)
.setConnectTimeout(10000)
.build();
context.setRequestConfig(config);
HttpGet httpGet = new HttpGet(uri);
CloseableHttpResponse response = httpClient.execute(httpGet, context);
HttpConnection conn = context.getConnection();
HttpEntity entity = response.getEntity();
try (Scanner in = new Scanner(entity.getContent(), ENC))
{
// do something
}
System.out.println("open=" + conn.isOpen()); // now open=true

HttpGet httpGet2 = new HttpGet(uri2); // on the same host with other path

// and so on
}

更新 2

一般来说,使用 conn.isOpen() 检查连接并不是检查连接状态的正确方法,因为:“内部 HTTP 连接管理器使用 ManagedHttpClientConnection 的实例作为代理管理连接状态和控制 I/O 操作执行的真实连接。如果托管连接被释放或被其消费者显式关闭,底层连接将与其代理分离并返回给管理器。即使服务消费者仍然持有对代理实例的引用,它不再能够执行任何 I/O 操作或更改真实连接的状态,无论是有意还是无意。” ( HttpClent Tutorial )

正如@oleg 指出的那样,跟踪连接的正确方法是使用 logger .

最佳答案

首先,您需要确保您正在使用的远程服务器支持保持 Activity 连接。只需简单地检查远程服务器是否在每个响应中返回 header Connection: Keep-AliveConnection: Closed 。对于 Close 案例 there is nothing你可以这样做。您可以使用 this online tool执行此类检查。

接下来,您需要实现 ConnectionKeepAliveStrategy,如 this manual 的第 #2.6 段中定义的那样.请注意,您可以使用现有的 DefaultConnectionKeepAliveStrategy since HttpClient version 4.0 , 这样您的 HttpClient 将按如下方式构造:

HttpClient client = HttpClients.custom()
.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
.build();

如果服务器支持,这将确保您的 HttpClient 实例将通过保持 Activity 机制重用相同的连接。

关于java - 如何使用 Apache HttpClient 获得持久的 HttpConnection?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46053067/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com