web-dev-qa-db-ja.com

http接続タイムアウトの問題

URLに接続しているHttpClientを使用しようとすると、問題が発生します。接続タイムアウトを設定した後でも、http接続のタイムアウトに時間がかかります。

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

ほとんどの場合、完璧に機能します。ただし、時々、http接続は永遠に実行され、setconnectiontimeoutを無視します。特に、電話がWi-Fiに接続されていて、電話がアイドリングしている場合はそうです。

したがって、電話がアイドリングした後、最初に接続しようとすると、http接続はsetconnectiontimeoutを無視して永久に実行されます。キャンセルして再試行すると、毎回チャームのように機能します。しかし、それが機能しない場合は、threadtimeoutエラーが発生します。別のスレッドを使用してみましたが、機能しますが、スレッドが長時間実行されていることはわかっています。

Wi-Fiがアイドル状態でスリープ状態になることは理解していますが、setconnectiontimeoutを無視する理由がわかりません。

誰でも助けることができます、idは本当に感謝しています。

17
Mark

これがあなたに役立つかどうかはわかりませんが、ここで共有する価値があると思います。タイムアウトのもので遊んでいるときに、割り当てることができる3番目のタイムアウトタイプがあることがわかりました。

// the timeout until a connection is established
private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */

// the timeout for waiting for data
private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */

// ----------- this is the one I am talking about:
// the timeout until a ManagedClientConnection is got 
// from ClientConnectionRequest
private static final long MCC_TIMEOUT = 5000; /* 5 seconds */

...

HttpGet httpGet = new HttpGet(url);
setTimeouts(httpGet.getParams());

...

private static void setTimeouts(HttpParams params) {
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
        CONNECTION_TIMEOUT);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
}
10
Vit Khudenko
Thread t=new Thread()
{
  public void run()
  {
    try 
    {
      Thread.sleep(absolutetimeout);
      httpclient.getConnectionManager().closeExpiredConnections();
      httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS);
      httpclient.getConnectionManager().shutdown();
      log.debug("We shutdown the connection manager!");
    }
    catch(InterruptedException e)
    {}
  }
};

t.start();
HttpResponse res= httpclient.execute(httpget);
t.interrupt();

それは皆さんが提案していることに沿ったものですか?

実行が開始されたら、実行をキャンセルする方法が正確にはわかりませんが、これは私にとってはうまくいくようでした。スレッドの3行のどれが魔法をかけたのか、それともそれらすべての組み合わせだったのかはわかりません。

1
Randy Baden

私は同じ問題に遭遇しました、多分Androidはこのパラメーターをサポートしていません。私の場合、私はThreadSafeClientConnManagerの3つのパラメーターすべてをテストしました

params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );

1番目と2番目は正常に機能しましたが、3番目は文書化されているように機能しませんでした。 DefaultHttpClient#execute()の実行中に、例外はスローされず、実行中のスレッドは無期限にブロックされました。

http://hc.Apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e65 を参照してください。
"...「http.conn-manager.timeout」を正の値に設定することで、接続マネージャーが接続要求操作で無期限にブロックしないようにすることができます。指定された範囲内で接続要求を処理できない場合期間ConnectionPoolTimeoutExceptionがスローされます。」

1
Chen Zhuo

HTTP接続をどのように行っていますか?これはスレッドの問題のようです。バックグラウンドスレッドを使用している場合は、登録されているタイムアウトとともにスレッドが強制終了される可能性があります。次回動作するという事実は、Androidコンポーネントで呼び出しを行い、そのコンポーネントでWAKE_LOCKを管理すれば、コードが動作することを示しています。とにかく、呼び出しに関する詳細情報を投稿してください。機構?

0

タイムアウトを自分で管理できます。これにより、接続がどのような状態になっても、許容可能な応答を受信しない限り、タイムアウトが発生し、http要求が中止されることを確信できます。

0
Tyler

スニペットから、タイムアウトを設定したかどうかは最終的には明確ではありませんbeforeHttpClient.executeMethod(..)を呼び出します。だからこれは私の推測です。

0
Waldheinz

問題はApacheHTTPクライアントにある可能性があります。 HTTPCLIENT-1098 を参照してください。 4.1.2で修正されました。

タイムアウト例外は、ロギングの目的で、DNSをIPに逆引きしようとします。これには、例外が実際に発生するまでさらに時間がかかります。

0
noam

Androidでのタイムアウトについても同様の問題が発生しました。それを解決するために、私が行ったことは、接続を確立しようとしている間、および接続への読み取りまたは書き込み中に電話をアイドル状態にしないようにするコマンドを使用しました。この場合も、おそらく一撃の価値があります。

0
S E

別のアプリケーションに対してアイドル/マルチタスクを実行すると、実行中のスレッドが停止して破棄される可能性があります。代わりに、接続コードをサービス内に配置する必要がありますか?:

http://developer.Android.com/reference/Android/os/AsyncTask.html http://developer.Android.com/reference/Android/app/IntentService.html

0
Marius K

Androidプラットフォームではこれを見ていませんが、他のプラットフォームでも同様のことが見られます。このような場合の解決策は、タイムアウトを自分で管理することです。別のスレッドを開始します(タイムアウトスレッド)リクエストを行うときタイムアウトスレッドは必要な時間をカウントダウンしますデータを受信する前にタイムアウトが期限切れになると、タイムアウトスレッドは元のリクエストをキャンセルし、新しいリクエストで再試行します。コーディングは難しいですが、少なくともあなたはそれが機能することを知っています。

0
Eric Giguere