wake-up-neo.com

Wie kann ich HttpClient Connection am Leben erhalten?

Ich arbeite an der Methode HttpClient POST. Ich muss HttpClient einmal erstellen und sollte Keep Alive Connection verwenden. Aber ich denke in meinem Fall, es wird jedes Mal eine neue Verbindung hergestellt.

Also muss ich eine Keep Alive - Verbindung für HttpClient verwenden.

Hier ist mein Code-Snippet, für jede Hilfe wäre ich sehr dankbar.

ClientConnectionManager mgr = httpclient_recv.getConnectionManager();
    hp = httpclient_recv.getParams();
    httpclient_recv = new DefaultHttpClient(
    new ThreadSafeClientConnManager(hp,mgr.getSchemeRegistry()), hp);

    while (true) {

        try {

            Java.util.logging.Logger.getLogger("org.Apache.http.wire")
                    .setLevel(Java.util.logging.Level.FINER);
            Java.util.logging.Logger.getLogger("org.Apache.http.headers")
                    .setLevel(Java.util.logging.Level.FINER);

            System.setProperty("org.Apache.commons.logging.Log",
                    "org.Apache.commons.logging.impl.SimpleLog");
            System.setProperty(
                    "org.Apache.commons.logging.simplelog.showdatetime",
                    "true");
            System.setProperty(
                    "org.Apache.commons.logging.simplelog.log.httpclient.wire",
                    "debug");
            System.setProperty(
                    "org.Apache.commons.logging.simplelog.log.org.Apache.http",
                    "debug");
            System.setProperty(
                    "org.Apache.commons.logging.simplelog.log.org.Apache.http.headers",
                    "debug");

            ByteArrayEntity bae = new ByteArrayEntity(byteData);
            bae.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
                    "binary/octet-stream"));

            httppost_recv.setHeader(HTTP.CONN_DIRECTIVE,HTTP.CONN_KEEP_ALIVE);
            httppost_recv.setEntity(bae);



            {
                System.out.println("res b4 response");
                 response_recv = httpclient_recv
                        .execute(httppost_recv);
                 response_recv.getEntity().consumeContent();
                System.out.println("res a4 response");
                if (response_recv != null) {
                    byteArray = EntityUtils.toByteArray(response_recv
                            .getEntity());
                    playing  = true;
                }
                        }
                 }

und auch logcat logs ist:

12-03 10:07:29.466: I/System.out(1529): res b4 response
12-03 10:07:29.646: D/org.Apache.http.wire(1529): >> "POST /ping HTTP/1.1[EOL]"
12-03 10:07:29.666: D/org.Apache.http.wire(1529): >> "Connection: Keep-Alive[EOL]"
12-03 10:07:29.686: D/org.Apache.http.wire(1529): >> "Content-Length: 1[EOL]"
12-03 10:07:29.705: D/org.Apache.http.wire(1529): >> "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.716: D/org.Apache.http.wire(1529): >> "Host: 192.168.1.36[EOL]"
12-03 10:07:29.725: D/org.Apache.http.wire(1529): >> "User-Agent: Apache-HttpClient/UNAVAILABLE (Java 1.4)[EOL]"
12-03 10:07:29.736: D/org.Apache.http.wire(1529): >> "[EOL]"
12-03 10:07:29.746: D/org.Apache.http.headers(1529): >> POST /ping HTTP/1.1
12-03 10:07:29.746: D/org.Apache.http.headers(1529): >> Connection: Keep-Alive
12-03 10:07:29.756: D/org.Apache.http.headers(1529): >> Content-Length: 1
12-03 10:07:29.756: D/org.Apache.http.headers(1529): >> Content-Type: binary/octet-stream
12-03 10:07:29.765: D/org.Apache.http.headers(1529): >> Host: 192.168.1.36
12-03 10:07:29.765: D/org.Apache.http.headers(1529): >> User-Agent: Apache-HttpClient/UNAVAILABLE (Java 1.4)
12-03 10:07:29.776: D/org.Apache.http.wire(1529): >> "[0x0]"
12-03 10:07:29.796: D/org.Apache.http.wire(1529): << "HTTP/1.1 200 OK[EOL]"
12-03 10:07:29.805: D/org.Apache.http.wire(1529): << "Server: gSOAP/2.8[EOL]"
12-03 10:07:29.816: D/org.Apache.http.wire(1529): << "Content-Type: binary/octet-stream[EOL]"
12-03 10:07:29.826: D/org.Apache.http.wire(1529): << "Content-Length: 2048[EOL]"
12-03 10:07:29.836: D/org.Apache.http.wire(1529): << **"Connection: close[EOL]"**
12-03 10:07:29.887: D/org.Apache.http.headers(1529): << HTTP/1.1 200 OK
12-03 10:07:29.896: D/org.Apache.http.headers(1529): << Server: gSOAP/2.8
12-03 10:07:29.896: D/org.Apache.http.headers(1529): << Content-Type: binary/octet-stream
12-03 10:07:29.906: D/org.Apache.http.headers(1529): << Content-Length: 2048
12-03 10:07:29.906: D/org.Apache.http.headers(1529): << **Connection: close**
12-03 10:07:29.916: I/System.out(1529): res a4 response
9
G M Ramesh

10: 07: 29.746: D/org.Apache.http.headers (1529): >> Verbindung: Keep-Alive

Sie fordern Keepalive an.

10: 07: 29.836: D/org.Apache.http.wire (1529): << "Connection: close [EOL]"

Der Server lehnt es ab.

Daran können Sie an Ihrem Ende nichts ändern.

8
user207421

Ab HTTP 1.1 ist Keep-Alive standardmäßig aktiviert. Sie müssten die Verbindung schließen, wenn Sie nicht möchten, dass sie beim Umgang mit HTTP 1.1 explizit wiederverwendet wird.

Für 1.0 ist ein Header das, was Sie für diese "Verbindung: Keep-Alive" festlegen. Dies deutet nur den Server an, den Sie die Verbindung wiederverwenden möchten. Unter Stress oder aus anderen Gründen kann sich der Server anders verhalten, als im Folgenden erläutert.

Für die meisten Zwecke sind die meisten Antworten hier richtig, wobei Sie Keep-Alive-Header hinzufügen und es funktioniert gut. Die folgende Erklärung gilt für die Szenarien, in denen Sie dies getan haben, aber es funktioniert immer noch nicht.


Die serverseitigen Probleme

Normalerweise würde sich eine Antwort auf ein Setup konzentrieren, bei dem sich der Server normal verhält, aber dies ist nicht ganz richtig. Server (wie Rudra ) sind so aufgebaut, dass sie sich in verschiedenen Situationen unterschiedlich verhalten. Keep-Alive enthält eine Reihe von Anforderungen, für die der Server Sie vor dem Trennen der Verbindung bereitstellt. Dies dient dazu, Dienste auch für andere Server bereitzustellen. Bei hoher Auslastung können einige Server die Anzahl der Keep-Alive-Anforderungen verringern für jede neue Verbindung serviert.

Es gibt auch eine Zeitüberschreitung, die von der letzten eingegangenen Anforderung abweicht, wenn in diesem Zeitfenster keine weiteren Anforderungen gestellt werden. Nur wenige moderne Server können dies auf der Grundlage ihrer aktuellen Kapazität ändern oder es unter Panikbedingungen auf 0 reduzieren, wodurch Keep-Alive bedeutungslos wird. Wenn der Server, mit dem Sie eine Verbindung herstellen möchten, solche Bedingungen (Rennen, Panik) durchläuft, wird Ihre Anfrage möglicherweise verworfen.


Die clientseitigen Probleme

Zur Dokumentation. Von hc.Apache.org :

HttpClient bemüht sich immer, Verbindungen wiederzuverwenden. Die Verbindungspersistenz ist standardmäßig aktiviert und erfordert keine Konfiguration. Dies kann unter Umständen zu Verbindungslecks und damit zu Ressourcenverlusten führen. Die einfachste Möglichkeit, die Verbindungspersistenz zu deaktivieren, besteht darin, einen Verbindungsmanager bereitzustellen oder zu erweitern, der das Schließen von Verbindungen beim Freigeben in der releaseConnection-Methode erzwingt.

HttpClient bietet diese (sprich: trivialen) Dinge "Out of the Box" an. Es gibt jedoch noch andere von Apache angebotene Dinge, die Sie hinzufügen können, um die Leistung zu verbessern.

ConnectionManager können beispielsweise für HttpClient angepasst werden.

Das, was die Keep-Alive-/Verbindungspersistenz blockieren kann, ist der Verbindungsmanager, den Sie möglicherweise verwenden (dies ist in Ihrem Fall nicht der Fall, aber in mehreren anderen Fällen möglicherweise der Fall). Dies ist möglicherweise eine völlig unbekannte/abstrakte Tatsache für Sie, wenn Sie das Client-Objekt zum Ausführen der Aufrufe von einer API erhalten. Ein Beispiel, wie dies angepasst werden kann, ist unten aufgeführt (aus der Dokumentation zur Apache-Verbindungsverwaltung).

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
cm.setMaxTotal(200);
// Increase default max connection per route to 20
cm.setDefaultMaxPerRoute(20);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(localhost), 50);

CloseableHttpClient httpClient = HttpClients.custom()
    .setConnectionManager(cm)
    .build();

(Weitere Informationen finden Sie in der Apache-Dokumentation zur Verbindungsverwaltung )

Wenn Sie mit diesem Problem konfrontiert sind, probieren Sie es ohne CM aus oder erstellen Sie ein eigenes HttpClient-Objekt. Es ist nicht erforderlich, ein CM auch für mehrere Verbindungen zu verwenden. Das eingebaute CM ist fair genug. Wenn Sie einen Leistungsverlust bemerken, können Sie Ihren eigenen Verbindungsmanager schreiben.

In Ihrem Fall ist Ihr Server jedoch nicht sehr unterstützend, und es kann sein, dass er Keep-Alive überhaupt nicht ehrt, selbst wenn Sie diese Header haben und was nicht. Sie müssen beim Senden einer neuen Anforderung an den Server auf Timeout-Header prüfen, um festzustellen, ob es sich bei dem Server um eine Beschwerde handelt.

3
Kumar Mani

Warum verwenden Sie nicht einfach den gleichen Client für alle Ihre Anfragen?

Ich habe an einer App gearbeitet, die viele Daten für viele Webdienste abfragen muss, und dafür verwende ich nur einen statischen Client und arbeite einwandfrei!

Ich habe eine Klasse erstellt, die den HttpClient zurückgibt, und eine weitere Klasse, die alle meine Anforderungen (POST und GET) verwaltet. Nett und einfach.