web-dev-qa-db-fra.com

Comment garder la connexion HttpClient Keep-Alive?

Je travaille HttpClient POST méthode. Je dois créer HttpClient une fois et dois utiliser Keep Alive Connection. Mais je pense que dans mon cas, cela établit une nouvelle connexion à chaque fois.

Donc, je dois utiliser un Keep Alive connection pour HttpClient.

Voici mon extrait de code, toute aide serait très appréciée.

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

et aussi logcat logs est:

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): >> Connexion: Keep-Alive

Vous demandez Keepalive.

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

Le serveur le refuse.

Vous ne pouvez rien faire à ce sujet de votre côté.

8
user207421

À partir de HTTP 1.1, Keep-Alive est activé par défaut. Vous auriez besoin de fermer la connexion si vous ne voulez pas qu'elle soit explicitement réutilisée lorsque vous utilisez HTTP 1.1.

Pour 1.0, un en-tête correspond à ce que vous avez défini pour cette "Connexion: Keep-Alive". Cela indique uniquement au serveur que vous souhaitez réutiliser la connexion. En cas de stress ou pour d'autres raisons, le serveur peut choisir d'agir différemment, comme expliqué ci-dessous.

Dans la plupart des cas, la plupart des réponses ici sont correctes, où vous ajoutez en-tête Keep Alive et cela fonctionne bien. L'explication suivante concerne les scénarios dans lesquels vous avez fait cela, mais cela ne fonctionne toujours pas.


Les problèmes côté serveur

Normalement, une réponse se concentre sur une configuration lorsque le serveur se comporte normalement, mais ce n'est pas complètement vrai. Les serveurs (comme Rudra ) sont conçus pour se comporter différemment dans différentes situations. Keep-alive vient avec un certain nombre de requêtes que le serveur vous servirait avant de mettre fin à votre connexion. Il permet également de servir les autres. Ainsi, en cas de charge élevée, certains serveurs peuvent recourir à la réduction du nombre de requêtes Keep-Alive. servi pour chaque nouvelle connexion.

Il existe également un délai d'attente défini à partir de la dernière demande reçue, qui pourrait éventuellement conduire à une déconnexion si aucune autre demande n'est faite dans cette fenêtre. Peu de serveurs modernes pourraient modifier cela en fonction de la capacité dont ils disposent pour le moment ou le laisser tomber à zéro dans des conditions de panique rendant le maintien en vie dénué de sens. Ainsi, si le serveur avec lequel vous essayez de vous connecter est soumis à l'une de ces conditions (de race, de panique), il peut choisir d'éliminer votre demande.


Les problèmes côté client

Aux fins de la documentation. De hc.Apache.org :

HttpClient fait toujours de son mieux pour réutiliser les connexions. La persistance de la connexion est activée par défaut et ne nécessite aucune configuration. Dans certaines situations, cela peut entraîner des fuites de connexions et donc une perte de ressources. Le moyen le plus simple de désactiver la persistance de la connexion consiste à fournir ou à étendre un gestionnaire de connexions qui force la fermeture des connexions lors de la publication dans la méthode releaseConnection.

HttpClient offre ces choses (lire: trivial) Out Of The Box. Cependant, Apache propose d’autres possibilités pour améliorer ses performances.

Les ConnectionManager (s), par exemple, peuvent être personnalisés pour HttpClient.

Ainsi, le gestionnaire de connexion que vous utilisez peut-être peut-être bloquer la persistance de la connexion/persistance/connexion (ce n'est pas le cas dans votre cas, mais peut-être dans plusieurs autres cas). Cela pourrait être un fait totalement inconnu/abstrait pour vous si vous obtenez l'objet Client pour effectuer les appels à partir d'une API. Un exemple de la manière dont cela peut être personnalisé est présenté ci-dessous (tiré de la documentation relative à la gestion des connexions Apache).

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

(veuillez consulter la documentation Apache sur la gestion des connexions pour plus de détails)

Si vous rencontrez ce problème, essayez sans CM ou créez votre propre objet HttpClient. Il n'est pas nécessaire d'utiliser un CM pour plusieurs connexions également. Le CM intégré est assez juste. Si vous constatez une perte de performance, vous pouvez écrire votre propre gestionnaire de connexions.

Dans votre cas, cependant, votre serveur n’est pas très favorable, il se peut qu’il n’honore pas du tout Garder en vie, même si vous avez ces en-têtes et ce qui ne l’est pas. Vous devez vérifier l'en-tête de délai d'attente en réponse lors de l'envoi d'une nouvelle demande au serveur pour confirmer que le serveur fait l'objet d'une réclamation.

3
Kumar Mani

Pourquoi n'utilisez-vous pas le même client pour toutes vos demandes ???

Je travaille sur une application qui doit demander beaucoup de données à de nombreux services Web. Pour cela, je n'utilise qu'un client statique et fonctionne parfaitement!

J'ai fait une classe qui retourne le HttpClient et une autre classe qui gère toutes mes demandes (POST et GET), Nice et facile;)