41 votes

Les requêtes HTTP Post utilisant HttpClient prennent 2 secondes, pourquoi?

Mise à jour: Trouvé la réponse moi-même, voir ci-dessous :-)

Salut,

Je suis actuellement codage d'une application android qui envoie des trucs dans le fond à l'aide de HTTP Post et AsyncTask. J'utilise le org.apache.http.client Forfait pour cette. J'ai basé mon code sur cet exemple.

Fondamentalement, mon code ressemble à ceci:

public void postData() {
    // Create a new HttpClient and Post Header
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://192.168.1.137:8880/form");

    try {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("id", "12345"));
        nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);

    } catch (ClientProtocolException e) {
     Log.e(TAG,e.toString());
    } catch (IOException e) {
     Log.e(TAG,e.toString());
    }
}

Le problème est que le httpclient.execute(..) de la ligne dure environ 1,5 à 3 secondes, et je ne comprends pas pourquoi. Juste de demander une page avec HTTP Get prend environ 80 ms ou alors, donc le problème ne semble pas être la latence du réseau lui-même.

Le problème ne semble pas être sur le côté serveur soit, j'ai aussi essayé les données de validation pour http://www.disney.com/ avec la même lenteur des résultats. Et Firebug indique 1 ms de temps de réponse lors de la Publication des données sur mon serveur local.

Ce qui se passe sur l'Émulateur et avec mon Nexus One (à la fois avec Android 2.2).

Si vous voulez voir le code complet, je l'ai mis sur GitHub.

C'est juste un mannequin programme HTTP Post à l'arrière-plan à l'aide de AsyncTask sur la simple pression d'un bouton. C'est ma première application Android, et mon premier code java pour un long moment. Et incidentially, aussi ma première question sur Stackoverflow ;-)

Des idées pourquoi httpclient.execute(httppost) prend si longtemps?

55voto

pableu Points 1481

Bon, j'ai résolu moi-même avec un peu plus de l'enquête. Tout ce que j'avais à faire était d'ajouter un paramètre qui définit la Version du protocole HTTP 1.1, comme suit:

HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpClient httpclient = new DefaultHttpClient(params);

J'ai trouvé cela grâce à la très belle HttpHelper Classe de et-rat de bibliothèque et quelques essais et d'erreurs.

Si je me souviens bien, HTTP 1.0 ouvre une nouvelle connexion TCP pour chaque demande. Le fait d'expliquer le grand retard?

Une requête HTTP de type POST prend maintenant entre 50 et 150 ms sur wi-fi et quelque chose entre 300 et 500 ms sur les réseaux 3G.

6voto

henri Points 61

Je ne suis pas sous Android, mais j'ai rencontré exactement le même type de problème sur la plate-forme Windows avec httpclient 4.0.1. Après un peu de casse-tête, j'ai trouvé la solution.

 HttpParams params = new BasicHttpParams();
//this how tiny it might seems, is actually absoluty needed. otherwise http client lags for 2sec.
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpClient httpClient = new DefaultHttpClient(params);
HttpResponse httpResponse;


HttpPost httpPost = new HttpPost("http://"+server+":"+port+"/");
StringEntity entity = new StringEntity(content, "utf-8");
entity.setContentType("text/plain; charset=utf-8"); 
httpPost.setEntity(entity);

httpResponse=httpClient.execute(httpPost);

String response = IOUtils.toString(httpResponse.getEntity().getContent(),encoding);
httpResponse.getEntity().consumeContent();

httpClient.getConnectionManager().shutdown();
return(response);
 

Je ne sais pas pourquoi la configuration des paramètres avec la version HTTP1.1 résout le problème. mais c'est le cas. même plus étrange encore, le symptôme n'apparaissait pas si une requête HTTP Get était exécutée.

Quoi qu'il en soit, j'espère que cela aidera certains là-bas!

h

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X