2016-07-18 40 views
0

In meiner Java-Client-Anwendung verbinde ich mich mit meinem Server mit HttpsURLConnection. Dies funktioniert alles gut, außer in bestimmten Momenten ist es keine Auszeit. Ich habe die Timeout-Parameter der Verbindung als solche (bis 5000 ms):Timeout hat keine Begrenzung? - 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; 
} 

ich alle Ausnahmen bin fangen, aber keiner registriert ist, so kann das Problem nicht abgefangene Ausnahme sein. Die Verbindung wird einfach nicht beendet. Ich wartete 3 Minuten und hatte keine Antwort. Ich könnte den Fehler einige Male reproduzieren, während ich das Netzwerk während der Ausführung einer Anfrage umschalte.

Auch manchmal gab es eine Antwort nach etwa einer Minute. Welches ist länger als die Timeouts.

Ich habe bereits versucht, den Thread zu unterbrechen, auf den die Anfrage nach einer Zeitüberschreitung gestellt wird, die HttpsURLConnection zu trennen. Aber es muss eine bessere Lösung geben. Ich würde gerne wissen, woher diese unbestimmte Zeitüberschreitung kommt.

Irgendwelche Ideen?

Vielen Dank!

+0

Mit welcher URL verbinden Sie sich? Ich glaube, die Antwort auf Ihre Frage kann von dem Server abhängen, den Sie treffen: Wenn es diesem Server nichts ausmacht, eine unbegrenzte offene Verbindung zu haben, könnte dies Ihre Beobachtungen erklären. –

+1

Die Ausnahme, die im Falle eines Timeouts ausgelöst wird, sollte [java.net.SocketTimeoutException] (https://docs.oracle.com/javase/7/docs/api/java/net/SocketTimeoutException.html) lauten, was Sie tun sollten schon fangen, da es keine Laufzeitausnahme ist (kann aber nicht sehen, wie Sie das in Ihrem Code machen). Beachten Sie auch, dass aus der [API] (https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#setConnectTimeout%28int%29): "Einige nicht-Standard-Implementation von diesem Die Methode ignoriert möglicherweise das angegebene Zeitlimit. Um das Verbindungszeitlimit anzuzeigen, rufen Sie getConnectTimeout() auf. ". Könnte ein Hinweis sein ... – Mena

+0

@Mena in der Tat, wenn ich das getConnectTimeout() Ergebnis drucke, bekomme ich immer 0 (unendlich), egal welchen Wert ich ihm zuweisen. Wir wissen nun, dass HttpsURLConnection eine "Nicht-Standard-Implementierung" der setConnectTimeout() -Methode hat. Aber wie kann ich die unendliche Auszeit trotzdem beschränken? – Zxifer

Antwort

1

Von meinem Kommentar

Die Ausnahme im Fall einer Auszeit geworfen sollte java.net.SocketTimeoutException sein, die Sie schon gefangen werden sollten, da es keine Laufzeitausnahme ist (kann nicht sehen, wie Sie, dass in Ihrem Code zu tun obwohl).

Beachten Sie auch, dass von der API:

Einige Nicht-Standard-implmentation dieser Methode die angegebenen Timeout ignorieren kann. Um die Verbindungszeitüberschreitung anzuzeigen, rufen Sie bitte getConnectTimeout().

Von Ihrem Kommentar

der Tat, wenn ich das getConnectTimeout() Ergebnis drucken, erhalte ich immer 0 (unendlich), unabhängig davon, welcher Wert I zu zuweisen. So wissen wir jetzt HttpsURLConnection hat eine "nicht-Standard-Implementierung" der setConnectTimeout() Methode. Aber wie kann ich das unendliche Timeout trotzdem einschränken?

Eine schnelle und hässliche Lösung

  • „Wrap around“ Ihr Code die Verbindung, indem es an die call außer Kraft setzen ein bewegtes Callable<String> Festlegung (parametrisierte Typ, dessen ist, was ich der Typ sein, übernehmen Ihrer result Variable).
  • Verwenden Sie aus dem Thread, der gerade dieses aufruft, einen Executor Singlethread, um Ihre neue Callable<String> einzureichen.
  • Rufen Sie dann get auf dem Future<String>, mit dem Timeout Ihrer Wahl, und behandeln Sie die TimeoutException entsprechend.

A (vielleicht) besser, langfristige Lösung

  • Blick in die Umsetzung der abstract class HttpsURLConnection Sie es zu tun mit, und sehen, ob es ein Fehler ist/kommunizieren, mit wem es umgesetzt.
+0

Vielen Dank für Ihre Antwort. Nachdem ich tiefer in meinen Code eingedrungen war, bemerkte ich, dass die Art und Weise, wie ich die Timeouts einstellte, falsch war. Ich habe Java-Einstellungen für die Timeout-Werte verwendet und diese wurden nicht richtig festgelegt. Mein Code scheint jetzt gut zu funktionieren, mit setConnectTimeout() und setReadTimeout(). Ihre schnelle und hässliche Lösung ist dennoch eine bessere Lösung in dem Sinne, dass sie auch andere (möglicherweise längere) Timeouts wie Windows 21 Sekunden Timeout verkürzt, wie in einem Kommentar hier erwähnt: http://stackoverflow.com/questions/14026223/ java-httpurlconnection-timeout-does-not-work – Zxifer

+0

@ Zxifer du bist willkommen. Ich schätze am Ende hängt alles davon ab, * was * du wirklich rausmessen willst - Async-Ausführungs-Idiome zu verwenden kann nützlich sein, wenn es um eine Reihe von Anweisungen geht, die nicht nur die tatsächliche Verbindung enthalten, die ziemlich gewöhnlich ist davon. – Mena