如何保持HttpClient连接保持活跃?

G M*_*esh 9 java android http httpclient http-post

我正在研究HttpClientPOST方法.我需要创建HttpClient一次,并且应该使用Keep Alive Connection.但我想在我的情况下,它每次都建立一个新的连接.

所以,我需要使用Keep Alive连接HttpClient.

这是我的代码片段任何帮助将不胜感激.

ClientConnectionManager mgr = httpclient_recv.getConnectionManager();
    hp = httpclient_recv.getParams();
    httpclient_recv = new DefaultHttpClient(
    new ThreadSafeClientConnManager(hp,mgr.getSchemeRegistry()), hp);

    while (true) {

        try {

            java.util.logging.Logger.getLogger("org.apache.http.wire")
                    .setLevel(java.util.logging.Level.FINER);
            java.util.logging.Logger.getLogger("org.apache.http.headers")
                    .setLevel(java.util.logging.Level.FINER);

            System.setProperty("org.apache.commons.logging.Log",
                    "org.apache.commons.logging.impl.SimpleLog");
            System.setProperty(
                    "org.apache.commons.logging.simplelog.showdatetime",
                    "true");
            System.setProperty(
                    "org.apache.commons.logging.simplelog.log.httpclient.wire",
                    "debug");
            System.setProperty(
                    "org.apache.commons.logging.simplelog.log.org.apache.http",
                    "debug");
            System.setProperty(
                    "org.apache.commons.logging.simplelog.log.org.apache.http.headers",
                    "debug");

            ByteArrayEntity bae = new ByteArrayEntity(byteData);
            bae.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
                    "binary/octet-stream"));

            httppost_recv.setHeader(HTTP.CONN_DIRECTIVE,HTTP.CONN_KEEP_ALIVE);
            httppost_recv.setEntity(bae);



            {
                System.out.println("res b4 response");
                 response_recv = httpclient_recv
                        .execute(httppost_recv);
                 response_recv.getEntity().consumeContent();
                System.out.println("res a4 response");
                if (response_recv != null) {
                    byteArray = EntityUtils.toByteArray(response_recv
                            .getEntity());
                    playing  = true;
                }
                        }
                 }
Run Code Online (Sandbox Code Playgroud)

以及logcat日志是:

12-03 10:07:29.466: I/System.out(1529): res b4 response
12-03 10:07:29.646: D/org.apache.http.wire(1529): >> "POST /ping HTTP/1.1[EOL]"
12-03 10:07:29.666: D/org.apache.http.wire(1529): >> "Connection: Keep-Alive[EOL]"
12-03 10:07:29.686: D/org.apache.http.wire(1529): >> "Content-Length: 1[EOL]"
12-03 10:07:29.705: D/org.apache.http.wire(1529): >> "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.716: D/org.apache.http.wire(1529): >> "Host: 192.168.1.36[EOL]"
12-03 10:07:29.725: D/org.apache.http.wire(1529): >> "User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)[EOL]"
12-03 10:07:29.736: D/org.apache.http.wire(1529): >> "[EOL]"
12-03 10:07:29.746: D/org.apache.http.headers(1529): >> POST /ping HTTP/1.1
12-03 10:07:29.746: D/org.apache.http.headers(1529): >> Connection: Keep-Alive
12-03 10:07:29.756: D/org.apache.http.headers(1529): >> Content-Length: 1
12-03 10:07:29.756: D/org.apache.http.headers(1529): >> Content-Type: binary/octet-stream
12-03 10:07:29.765: D/org.apache.http.headers(1529): >> Host: 192.168.1.36
12-03 10:07:29.765: D/org.apache.http.headers(1529): >> User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
12-03 10:07:29.776: D/org.apache.http.wire(1529): >> "[0x0]"
12-03 10:07:29.796: D/org.apache.http.wire(1529): << "HTTP/1.1 200 OK[EOL]"
12-03 10:07:29.805: D/org.apache.http.wire(1529): << "Server: gSOAP/2.8[EOL]"
12-03 10:07:29.816: D/org.apache.http.wire(1529): << "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.826: D/org.apache.http.wire(1529): << "Content-Length: 2048[EOL]"
12-03 10:07:29.836: D/org.apache.http.wire(1529): << **"Connection: close[EOL]"**
12-03 10:07:29.887: D/org.apache.http.headers(1529): << HTTP/1.1 200 OK
12-03 10:07:29.896: D/org.apache.http.headers(1529): << Server: gSOAP/2.8
12-03 10:07:29.896: D/org.apache.http.headers(1529): << Content-Type: binary/octet-stream
12-03 10:07:29.906: D/org.apache.http.headers(1529): << Content-Length: 2048
12-03 10:07:29.906: D/org.apache.http.headers(1529): << **Connection: close**
12-03 10:07:29.916: I/System.out(1529): res a4 response
Run Code Online (Sandbox Code Playgroud)

use*_*421 8

10:07:29.746:D/org.apache.http.headers(1529):>>连接:Keep-Alive

您正在请求keepalive.

10:07:29.836:d/org.apache.http.wire(1529):<< "连接:关闭[EOL]"

服务器拒绝它.

在你的最后,你无能为力.

  • '你请求keepalive'意味着你的代码是对的,不是吗?并且'你无能为力'对我来说似乎已经非常清楚了.我认为没有必要提出这些补充问题. (5认同)

Kum*_*ani 6

从 HTTP 1.1 开始,keep-alive 是默认启用的。如果您不希望在处理 HTTP 1.1 时显式重用它,则需要关闭连接。

对于 1.0,标题是您为此“连接:保持活动”设置的内容,这只会提示您要重用连接的服务器。当处于压力或其他原因时,服务器可能会选择不同的行为,如下所述。

对于大多数目的,这里的大多数答案都是正确的,在其中添加 keep alive 标头并且效果很好。以下说明适用于您这样做但仍然不起作用的情况。


服务器端问题

通常,当服务器行为正常时,答案会集中在设置上,但这并不完全正确。服务器(如Rudra)被构建为在不同情况下表现不同。Keep-alive 带有许多请求,服务器会在断开连接之前为您提供服务,这是为了允许为其他人提供服务,因此在高负载的情况下,某些服务器可能会减少保持连接请求的数量为每个新连接服务。

还有一个从收到的最后一个请求开始的超时设置,如果在那个时间窗口内没有进一步的请求,它最终会导致断开连接。很少有现代服务器会根据他们目前的容量来改变这一点,或者在恐慌情况下将其降至 0,从而使保持活动变得毫无意义。因此,如果您尝试连接的服务器正在经历任何此类(竞争、恐慌)情况,它可能会选择放弃您的请求。


客户端问题

用于文档目的。从hc.apache.org

HttpClient 总是尽力重用连接。默认情况下启用连接持久性,无需配置。在某些情况下,这可能会导致连接泄漏,从而导致资源丢失。禁用连接持久性的最简单方法是在 releaseConnection 方法中提供或扩展一个连接管理器,该管理器在释放时强制关闭连接。

HttpClient 提供了这些(阅读:琐碎的)开箱即用的东西。但是仍然有其他东西是由 Apache 提供的,您可以添加这些东西来提高它的性能。

例如,可以为 HttpClient 定制 ConnectionManager(s)。

因此,可以阻止保持活动/连接持久性的是您可能正在使用的连接管理器(这在您的情况下不是真的,但在其他几种情况下可能是真的)。如果您正在获取用于从某些 API 进行调用的 Client 对象,这对您来说可能是一个完全未知/抽象的事实。下面列出了如何自定义的示例(来自 Apache 连接管理文档)

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
cm.setMaxTotal(200);
// Increase default max connection per route to 20
cm.setDefaultMaxPerRoute(20);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(localhost), 50);

CloseableHttpClient httpClient = HttpClients.custom()
    .setConnectionManager(cm)
    .build();
Run Code Online (Sandbox Code Playgroud)

有关连接管理的更多详细信息,请参阅Apache 文档

如果您遇到此问题,请尝试不使用 CM 或创建您自己的 HttpClient 对象。也没有必要为多个连接使用 CM。内置的 CM 足够公平。如果您发现性能下降,您可以编写自己的连接管理器。

但是,在您的情况下,您的服务器不是很支持它可能根本不支持 Keep-alive,即使您有这些标头和什么没有。您需要在响应中检查超时标头,在向服务器发送新请求中的保持活动以建立该服务器是投诉。