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

我正在使用HttpClient POST方法。 我需要创build一次HttpClient ,并应使用Keep Alive Connection。 但我认为,就我而言,它每次都build立一个新的连接。

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

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

 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; } } } 

还有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 

Related of "如何保持HttpClient连接保持活动?"

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

您正在请求Keepalive。

10:07:29.836:D / org.apache.http.wire(1529):<< “Connection:close [EOL]”

服务器拒绝它。

你无能为力。

从HTTP 1.1开始,保持活动状态是默认启用的。 如果您不希望在处理HTTP 1.1时明确重用连接,则需要closures连接。

对于1.0,标题是你为这个“Connection:Keep-alive”设置的内容。这只是暗示你想要重用连接的服务器。 当处于压力或其他原因时,服务器可能会select采取不同的行为,如下所述。

对于大多数的目的,这里的大多数答案是正确的,在你添加保持活着的头,它运作良好。 以下说明适用于您所做的情况,但仍然无效。


服务器端问题

通常情况下,服务器正常运行时,答案将集中在一个设置上,但这不完全正确。 服务器(如Rudra )的构build方式在不同的情况下有所不同。 保持活着状态会伴随着服务器在您断开连接之前为您提供的一系列请求,这是为了让其他人也可以服务,所以在高负载的情况下,一些服务器可能会采取减less保持活动请求服务于每个新的连接。

从最后收到的请求还有一个超时设置,如果在该时间窗口内没有进一步的请求,最终会导致断开连接。 很less有现代服务器可能会根据当前的容量来改变它,或者在恐慌条件下将其降为0,从而保持活力毫无意义。 因此,如果您尝试连接的服务器正在经历任何这样的(比赛,恐慌)情况,它可能会select放弃您的请求。


客户端问题

为了文档的目的。 来自hc.apache.org :

HttpClient总是尽最大努力重用连接。 连接持久性默认情况下处于启用状态,不需要configuration。 在某些情况下,这可能会导致连接泄漏,从而导致资源损失。 禁用连接持久性的最简单方法是在releaseConnection方法中提供或扩展一个强制closures连接的连接pipe理器。

HttpClient提供这些(阅读:微不足道)的东西开箱。 但是还有其他的东西是由Apache提供的,你可以添加它来提高性能。

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

所以可以阻止保持活动/连接持久性的东西是你可能正在使用的连接pipe理器(在你的情况下,这不是真的,但在其他几种情况下也是如此)。 如果您正在从某个API获取调用的Client对象,那么对您而言,这可能是一个完全未知的/抽象的事实。 下面列出了一个如何定制的例子(来自Apache连接pipe理文档)

 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(); 

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

如果你面对这个问题,可以尝试一下没有CM,或者创build你自己的HttpClient对象。 对于多个连接也没有必要使用CM。 内置的CM是够公平的。 如果您看到性能下降,您可以编写自己的连接pipe理器。

然而,在你的情况下,你的服务器并不是非常支持,即使你有这些头文件,也不能保持活着。 您将需要检查超时标题作为响应,在向服务器发送新的请求中保持活动状态,以确定该服务器已投诉。

你为什么不把所有的请求都用同一个客户?

我一直在研究一个应用程序,它需要向很多Web服务请求大量数据,为此我只使用一个静态客户端,并且工作起来非常完美!

我做了一个类,返回HttpClient和另一个类来pipe理我所有的请求(POST和GET),很好很容易;)