2017-08-04 20 views
-1

Gibt es eine Möglichkeit, Socket-Level-Optionen (wie SO_KEEPALIVE) für ein JDK stdlib HttpUrlConnection zu setzen? Ich versuche einen Weg zu finden, HTTP-Anfragen zu bekommen, die nicht gelegentlichen "hängenden" Verbindungen zum Opfer fallen (die anscheinend aufgrund von Netzwerkpaketverlusten auftreten). Ein robuster HTTP-Client. Ich weiß, dass es die setReadTimeout Methode gibt, aber ich versuche, etwas zu finden, um den TCP-Strom wieder ins Leben zu schubsen, anstatt es einfach abzubrechen, wie das Lesezeitlimit scheint. Oder berichten Sie zumindest, dass der Verbindungsfehler aufgetreten ist, anstatt für immer an einem Lesevorgang zu hängen. Aber das erlaubt auch, dass das Lesen "wann immer es will" zurückkommt, vorausgesetzt die Verbindung ist "immer noch aktiv".HttpUrlConnection SO_KEEPALIVE

Mit einigen Untersuchungen scheint es, dass die Standardeinstellung für SO_KEEPALIVE für die C-Layer- und Java-Level-Sockets "aus" ist.

+1

Sind Sie mit der Verwendung von HttpUrlConnection verheiratet? Apache HttpClient hat wahrscheinlich wonach Sie suchen. [HttpClient] (https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/) – drelliot

+0

@drelliot Ich schätze, du hast Recht, fühlen Sie sich frei, um eine Antwort zu machen, und ich werde akzeptiere es :) – rogerdpack

Antwort

1

Das auf nicht ein, sondern drei Täuschungen beruht.

  1. SO_KEEPALIVE "schubst den TCP-Stream nicht ins Leben zurück", trotz seines schlecht gewählten Namens. Es erkennt nur tote Verbindungen nach einem Standardintervall von zwei Stunden. Es ist nicht das, wonach du suchst.

  2. Ein Lese-Timeout bricht die Verbindung nicht ab. Es wirft eine SocketTimeoutException. Die Verbindung ist noch aktiv und ein nachfolgender Lesevorgang ist möglicherweise erfolgreich.

  3. Gelöschte Pakete werden in TCP erkannt und erneut übertragen.

Verwenden Sie ein Lese-Timeout.

+0

Ich hatte gehofft, dass SO_KEEPALIVE periodisch sein würde und irgendwie die andere Seite alarmiert "Ich habe dein letztes Paket nicht bekommen, sende es nochmal!" aber es scheint so selten zu sein, dass die andere Seite die Verbindung wahrscheinlich schon getrennt haben wird. Davon abgesehen würde zumindest die sendende Seite mit einem Reset antworten, um zu benachrichtigen "hey, diese Pipe ist kaputt!" Also, wie du sagtest, wäre das Setzen eines (großen) Lese-Timeouts "so gut wie die Verwendung von SO_KEEPALIVE" für mein Szenario. Wenn ich jedoch wollte, dass sehr lange Lesevorgänge immer noch erfolgreich sind (oder Live-Timeouts auf Intermediate-Routern vermeiden), möchte ich vielleicht SO_KEEPALIVE, ja? :) – rogerdpack

+0

@rogerdpack Nein. SO_KEEPALIVE tut nicht, was Sie denken. – EJP

+0

Ja, meine anfängliche Hoffnung war sozusagen "unbegründet", vielleicht hast du meinen Kommentar falsch gelesen oder missverstanden? Ich sagte, ich sehe jetzt, dass es nicht das tut, was ich mir erhofft habe, aber unter bestimmten Umständen immer noch einen gewissen Nutzen haben kann. Prost! – rogerdpack

-2

Anscheinend ist die Antwort „verwenden Sie eine andere HTTP-Client-Bibliothek als den Standard“