2016-07-18 14 views
0

私のJavaクライアントアプリケーションでは、HttpsURLConnectionを使用して自分のサーバーに接続しています。これは、タイムアウトしない特定の瞬間を除いて、すべて正常に動作します。私は(5000ミリ秒)のような接続のタイムアウトパラメータを設定します。タイムアウトには制限はありませんか? - HttpsURLConnection

HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); 

// timeouts 
con.setConnectTimeout(5000); 
con.setReadTimeout(5000); 

con.setRequestMethod("put"); 
con.setDoInput(true); 
con.setDoOutput(true); 
con.setRequestProperty("Content-length", String.valueOf(output.length())); 
OutputStreamWriter os = new OutputStreamWriter(con.getOutputStream(), "UTF-8"); 
BufferedWriter writer = new BufferedWriter(os); 
writer.write(output); 
writer.close(); 
os.close(); 

con.connect(); 

int respCode = con.getResponseCode(); 

if(respCode == 200) { 
     InputStreamReader is = new InputStreamReader(con.getInputStream()); 
     BufferedReader br = new BufferedReader(is); 
     String input; 
     String respBody = ""; 
     while ((input = br.readLine()) != null){ 
      respBody += input; 
     } 
     br.close(); 
     is.close(); 
     this.result = respBody; 
} 

私はすべての例外をキャッチしていますが、どれが登録されていないので、問題がキャッチされない例外にすることはできません。接続は単にタイムアウトしません。私は3分待って応答がなかった。リクエストの実行中にネットワークを切り替えながら、バグを数回再現することができました。

また、約1分後に応答があったこともあります。タイムアウトよりも長い。

タイムアウト後に要求が行われたスレッドに割り込みを試み、HttpsURLConnectionを切断しました。しかしそれ以上の解決策が必要です。私はこの無期限のタイムアウトがどこから来るのか知りたいです。

アイデア?

ありがとうございます!私のコメントから

+0

どのURLに接続していますか?あなたの質問に対する答えは、あなたが叩いているサーバーに依存すると考えられます。このサーバーが無期限のオープン接続を気にしない場合、これはあなたの観察を説明することができます。 –

+1

タイムアウトの場合にスローされる例外は、[java.net.SocketTimeoutException](https://docs.oracle.com/javase/7/docs/api/java/net/SocketTimeoutException.html)である必要があります。実行時の例外ではないので、すでにキャッチしているはずです(あなたのコードでそれをどうやって行うのか分かりません)。また、[API](https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#setConnectTimeout%28int%29)から、次のように注意してください。「これのいくつかの非標準的な実装メソッドは、指定されたタイムアウトを無視することがあります。接続タイムアウトセットを確認するには、getConnectTimeout()を呼び出してください。 "ヒントになるかもしれません... – Mena

+0

@Mena実際にgetConnectTimeout()の結果を出力すると、どの値に割り当てても、常に0(無限)になります。そこで、HttpsURLConnectionにsetConnectTimeout()メソッドの「非標準実装」があることが分かりました。それでも、無限のタイムアウトをどのように制限できますか? – Zxifer

答えて

1

時間外の場合にスローされた例外は、それが実行時例外ではないとして、あなたがすでにキャッチしなければならないjava.net.SocketTimeoutException、する必要があります(あなたのコードでそれを行う方法を確認することはできませんしかし)。

この方法のいくつかの非標準implmentationが 指定されたタイムアウトを無視することがあります。

はまた、APIからのことに注意してください。接続タイムアウト設定を確認するには、 getConnectTimeout()に電話してください。

あなたのコメントから

私はgetConnectTimeout()結果を印刷するとき確かに、私はいつもかかわらず、私はそれに割り当てた値が、0 (無限)を取得しません。そこで、 HttpsURLConnectionには、 setConnectTimeout()メソッドの「非標準実装」があります。しかし、どうすれば無限のタイムアウトを制限することができますか?

迅速かつ醜いソリューション

  • (パラメータ化I型タイプであることを前提とするものであるCallable<String>callオーバーライドにそれを移動して接続を確立してコードを「包み込みます」あなたのresult変数の)
  • 現在この呼び出し元のスレッドから、シングルスレッドExecutorを使用して、新しいCallable<String>を送信してください。
  • Future<String>getを呼び出し、タイムアウトを選択して、それに応じてTimeoutExceptionを処理します。

A(多分)、より良い、長期的な解決策

  • abstract class HttpsURLConnectionあなたが扱っているの実装に見て、バグがあるかどう/それを実現し、誰と通信ご覧ください。
+0

お返事ありがとうございました。コードを深く掘り下げた後、タイムアウトを設定する方法が間違っていたことに気付きました。タイムアウト値としてJava Preferencesを使用しましたが、これらは正しく設定されていませんでした。私のコードは今、setConnectTimeout()とsetReadTimeout()を使って正常に動作しているようです。それにもかかわらず、あなたのすばやく醜い解決策は、ここでのコメントで言及されているように、ウィンドウの21秒のタイムアウトなど、短い(おそらく長くなる)タイムアウトを短くカットするという意味で、より良い解決策です:http://stackoverflow.com/questions/14026223/ java-httpurlconnection-timeout-does-not-work – Zxifer

+0

@ Zxiferようこそ。私は最終的にそれがすべて*あなたが本当にタイムアウトしたいものに依存していると思う - 非同期実行慣用句を使用すると、実際の接続を囲むだけでなく、それの。 – Mena

関連する問題