2011-01-02 70 views
16

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

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

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

ほとんどの場合、完全に機能します。しかし、毎晩、http接続は常に実行され、setconnectiontimeoutは無視されます。特に、電話機が無線LANに接続されていて、電話機がアイドリングしていた場合は無視されます。

電話がアイドル状態になった後、初めて接続しようとすると、http接続はsetconnectiontimeoutを無視し、キャンセルしてもう一度やり直してみると、毎回魅力的に機能します。しかし、それは動作しないその1回はthreadtimeoutエラーを作成する、私は別のスレッドを使用して、それは動作しますが、私はスレッドが長い時間実行されていることを知っている。

私は無線LANがアイドル状態で眠りにつくことを理解していますが、その理由を理解していません。setconnectiontimeout

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

+0

あなたはどのプラットフォームについて話していますか? –

+0

HTTP接続は、接続が本当に接続されていると考えているため、タイムアウトを「無視」する可能性があります。最初の握手は成功しましたが、パイプ(またはあなたの場合は空気)から何も出ません。たぶんあなたの電話は接続を受け入れ続ける傾向がありますが、アイドル時にはすぐ​​に忘れてしまいます。この問題が発生する前に交換された個々のフレームをキャプチャして調べると、おそらくもっと多くのことがわかります。 –

答えて

0

許容される応答を受信しない限りタイムアウトが発生し、http要求が中止されない限り、接続の状態に関係なく確実にタイムアウトを管理できます。

+0

まず、皆さん、お手伝いをしてくれてありがとうございます。@ Arhimed、私はそれを試みましたが、うまくいきませんでした。 – Mark

+0

私はテストを行った、私はインターネットを持っていない無線LANに私の電話を接続し、私はあなたのチューブアプリをクリックした。私のアプリのように、接続がないことを知るのに30秒かかった。それは私を夢中にさせている、タイムアウトの接続を無視する方法。 – Mark

+1

これは、インターネットにアクセスできない無線LANの場合、URLが直接IPアドレスではなくホスト名である場合、接続が確立されていないためです。あなたが待っているすべての時間は、ホスト名を解決しようとするのに費やされています。 – Chochos

10

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

// 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); 
} 
+1

Android 2.01.Firstのすべての、あなたの助けのためにみんなありがとうございました。@ Arhimed、私はそれを試みた、それは感謝しても動作しませんでした。この問題は次のいずれかの場合にのみ発生します:1 - 私の電話が無線LANに接続されていて、Wi-Fiにインターネットにアクセスできない場合。この場合タイムアウトはキャッチされておらず、約30秒かかります。 2_電話機が無線LANに接続されていて、Wi-Fiがインターネットにアクセスできる場合。電話機が少なくとも2分間アイドル状態になった後、イニシャル接続には約30秒かかります。他のすべての試みは、完璧に動作します。 – Mark

+1

@マーク:あなたのアプリがネイティブYouTubeアプリと同じ振る舞いをしているなら、あなたはよく眠ることができると思います(ネイティブアプリは、できるだけAPIを使用できるトッププロによるコードです)。時には、私たちのコントロールからちょうど外れているケースがあります。別の慰めのメモ - 30秒は、例えば、あなたが2分を持っていて、それを変更できないところのBlackBerryと比較するならばそれほど多くはありません。 ;) –

0

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

0

Androidプラットフォームではこれを見たことはありませんが、他のプラットフォームでも同様のことが起こりました。このような場合の解決方法は、自分でタイムアウトを管理することです。あなたの要求をするときに別のスレッド(タイムアウトスレッド)を起動します。タイムアウトスレッドは、所要時間をカウントダウンします。データを受信する前にタイムアウトが切れると、タイムアウトスレッドは元の要求をキャンセルし、新しい要求で再試行します。コードは難しくなりますが、少なくともそれが機能することはわかっています。

0

スニペットからタイムアウトをに設定した場合、の前にHttpClient.executeMethod(..)と設定すると、最終的にクリアされません。だから私の推測です。

0

まあ、別のアプリケーションにアイドル/マルチタスクすると、実行中のスレッドが停止して破棄される可能性があります。たぶん、あなたは

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

0

がどのようにHTTP接続を作っている?:代わりに、サービス内の接続コードを置く必要がありますか?これはスレッドの問題のようです。バックグラウンドスレッドを使用している場合は、登録されたタイムアウトとともにスレッドが強制終了されることがあります。あなたがアンドロイドコンポーネントで呼び出しを行い、WAKE_LOCKを自分で管理すると、次回に動作するということは、コードが動作することを伝えます。とにかく呼び出し元のメカニズムに関する情報を投稿してください。

1
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行のうちどれが魔法をしたのか、それともすべての組み合わせであるのかはわかりません。

+0

実際には、これはうまくいくようには見えません。私は本当にそれをしたくないので、自分自身のスレッドで実行する必要がありますか?ちょうどそれを殺す方法はありますか? –

1

私は同じ問題を抱えていますが、Androidがこのパラメータをサポートしていない可能性があります。私の場合は iは、第一および第二の罰金働いたThreadSafeClientConnManager

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

のためにすべての3つのパラメータをテストしたが、文書化されているように第三は動作しませんでした。 DefaultHttpClient#execute()が実行されているときに例外がスローされず、実行中のスレッドが無期限にブロックされました。

は、一つは正の値に 『http.conn-manager.timeout』を設定することで、接続要求操作で無期限にブロックしない接続マネージャを確保することができます...「http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
参照してください。接続要求をサービスすることができない場合指定された期間内にConnectionPoolTimeoutExceptionがスローされます。

0

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

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