2012-03-29 12 views
20

私は、ApacheからHttpClientを頻繁に使用する長時間実行するアプリケーションを開発しています。HttpClientが例外なくスタックされています

私の最初のテストでは、アプリケーションはちょうど立ち往生するまで完全に動作しました。それは停止されなかった、それは何も例外をスローしなかった、それはただ何もしないで座っている。

私は今すぐ2回目の走行をして時間を止め、約1時間後に停止しました。 24時間のコンティニュアントランニング。また、私はそれを実行していた私のラップトップのインターネット接続が、アプリケーションが立ち往生した正確な時点で終了していることに気づいた。私はWLANアダプタを再起動して、ネットが再び動作するようにしなければならなかった。

接続が再開しても、アプリケーションは正常に動作しませんでした。そして今、もう一度立ち往生した。

私はHttpClientで認識していないタイムアウトコントローラはありますか?接続が切断されたときにアプリケーションが例外をスローしないのはなぜですか?

クライアントを使用する部分は次のようになります。

public HttpUtil(ConfigUtil config) { 
    this.config = config; 

    client = new DefaultHttpClient(); 
    client.getParams().setParameter(HttpProtocolParams.USER_AGENT, this.config.getProperty("httputil.userAgent")); 
} 

public String getContentAsString(String url) throws ParseException, ClientProtocolException, IOException { 
    return EntityUtils.toString(
      client.execute(
        new HttpGet(url)).getEntity()); 
} 

アプリケーションでは、必要なURLに繰り返しhttputil.getContentAsString()が呼び出されます。

+0

エンティティが空の文字列である可能性があります。 – kasavbere

+0

私のメソッドはまだ空の文字列を返すでしょうか?または、少なくとも例外をスローしますか? –

+1

私は同じ問題があります。 httpEntity.consumeContent()は私を保存します。 http://stackoverflow.com/questions/9505358/android-httpclient-hangs-on-second-request-to-the-server-connection-timed-out – JamesC

答えて

8

このコードは廃止予定です(HttpParamsなどを入手してください)。より良い方法は次のとおりです。

RequestConfig defaultRequestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.BEST_MATCH).setExpectContinueEnabled(true).setStaleConnectionCheckEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build(); 

HttpGet httpGet = new HttpGet(url);  
RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig).setSocketTimeout(5000).setConnectTimeout(5000).setConnectionRequestTimeout(5000).build(); 
httpGet.setConfig(requestConfig); 
6

使用しているHttpClientのバージョンは述べていませんが、バージョン4と仮定すると、this blog articleは何をすべきかを説明しています。

DefaultHttpClient httpClient = new DefaultHttpClient(); 
HttpParams params = httpClient.getParams(); 
HttpConnectionParams.setConnectionTimeout(httpParams, connectionTimeoutMillis); 
HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis); 
+2

これは現在廃止予定です –

3

デフォルトでは、HttpClientはタイムアウトしません(これが原因で問題が発生します)。あなたが記述しているのはハードウェアの問題かもしれません。ネットワークアダプタが壊れた場合、HttpClientがハングします。ここ

を含むDefaultHttpClientのコンストラクタの一部としてHttpParamsからparameters設定されている

http.socket.timeout:待ちタイムアウトであるソケットタイムアウト ミリ秒(SO_TIMEOUT)を定義データの場合は を、連続した2つのデータ間の最大期間の非アクティブ期間は です)。タイムアウト値ゼロは、無限の タイムアウトとして解釈されます。このパラメータには、java.lang.Integer型の値が必要です。 このパラメータが設定されていない場合、読み取り操作はタイムアウトしません(無限 タイムアウト)。

これは接続でタイムアウトを設定するため、設定されたタイムアウト後に例外がスローされます。

3

私はすべてのタイムアウトの設定がうまくいっていますが、httpチャンクを行うURLは見つかっていますが、結果は送信されません(クロムでうまく動作しますが、httpクライアントではタイムアウトを設定しても永久にハングします)。幸いにも私はサーバーを所有していて、ゴミを返すだけで、もはやハングしません。これは非常にユニークなバグのようですが、httpクライアントは何らかの空のチャンクケースをうまく処理しません(しかし、私は遅れるかもしれませんが)....私はそれが空のデータとそのURLを持つ同じURLで毎回ハングすることを知っていますhttp chunking csvがhttpクライアントにダウンロードされます。

6

バージョン4.4では、ユーザーuser2393012とStephen Cの両方の回答は廃止されました。別の方法があるかどうかはわかりませんが、私がやる方法は、ビルダーのパラダイムであるHTTPClientBuilderを使用することです。

Ex。 OPも言及したものに

HttpClients.custom().setConnectionTimeToLive(1, TimeUnit.MINUTES).build() 

(それは実際にはOPの問題だったかもしれない)非常に同様の問題が起こりますが、クライアントごとに2つの接続のみにデフォルトの同時接続を設定することにより、Apacheのためです。これを解決するには、可能な場合には最大接続数を増やすか閉じてください。最大接続数を増やすには

HttpClients.custom().setMaxConnPerRoute(100000).build() 

接続を閉じるには、あなたがBasicHttpClientConnectionManagerを使用して

3

ためにcloseメソッドを呼び出すことができます私は同じ問題を持っていた、それは私はしなかった原因を立ち往生DefaultHttpClientを閉じます。
だから、これは間違っている:

try{ 
    DefaultHttpClient httpclient = new DefaultHttpClient(); 
    ... 
} catch (Exception e){ 
    e.PrintStackTrace(); 
} 

そして、これは正しいです:

try (DefaultHttpClient httpclient = new DefaultHttpClient()){ 
    ... 
} catch (Exception e){ 
    e.PrintStackTrace(); 
} 

はそれが誰かに役立ちます願っています。

4

私は私の場合は(HttpClient hangs on socketRead0 with successfully executed method)別のスレッドで

を同様の答えを与えた、私はリクエストに応じてではなく、SSL接続の確立時に使用される接続ソケット上のConnectionTimeoutとsocketTimeoutを設定しました。その結果、私はSSLハンドシェイク中にいつかハングアップします。以下は、v4.4を使用して3つのタイムアウトをすべて設定するコードです(v4.5でもテスト済み)

// Configure the socket timeout for the connection, incl. ssl tunneling 
connManager = new PoolingHttpClientConnectionManager(); 
connManager.setMaxTotal(200); 
connManager.setDefaultMaxPerRoute(100); 

SocketConfig sc = SocketConfig.custom() 
    .setSoTimeout(soTimeoutMs) 
    .build(); 

connManager.setDefaultSocketConfig(sc); 

HttpClient client = HttpClients.custom() 
      .setConnectionManager(connManager) 
      .setConnectionManagerShared(true) 
      .build(); 

// configure the timeouts (socket and connection) for the request 
RequestConfig.Builder config = = RequestConfig.copy(RequestConfig.DEFAULT); 
config.setConnectionRequestTimeout(connectionTimeoutMs); 
config.setSocketTimeout(socketTimeoutMs); 

HttpRequestBase req = new HttpGet(uri); 
req.setConfig(config.build()); 

client.execute(req); 
関連する問題