web-dev-qa-db-fra.com

problèmes de délai de connexion http

Je rencontre un problème lorsque j'essaie d'utiliser la connexion HttpClient à une URL. La connexion http prend plus de temps pour expirer, même après avoir défini une expiration du délai de connexion.

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

Cela fonctionne parfaitement la plupart du temps. Cependant, de temps en temps, la connexion http fonctionne pour toujours et ignore la setconnectiontimeout, en particulier lorsque le téléphone est connecté au wifi, et que le téléphone était inactif.

Ainsi, lorsque le téléphone est en veille, la première fois que j'essaie de me connecter, la connexion http ignore la setconnectiontimeout et s'exécute indéfiniment. Après l'avoir annulée et réessayée, elle fonctionne toujours comme un charme. Mais une fois que cela ne fonctionne pas, cela crée une erreur threadtimeout, j'ai essayé d'utiliser un autre thread, cela fonctionne, mais je sais que le thread est en cours d'exécution depuis longtemps.

Je comprends que le wifi s'endort au ralenti, mais je ne comprends pas pourquoi il ignore la setconnectiontimeout.

Tout le monde peut aider, id vraiment apprécié.

17
Mark

Je ne sais pas si cela vous aide, mais je pense que cela vaut la peine de le partager ici. Tout en jouant avec les éléments de timeout que j'ai trouvés, il existe un troisième type de timeout que vous pouvez affecter:

// the timeout until a connection is established
private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */

// the timeout for waiting for data
private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */

// ----------- this is the one I am talking about:
// the timeout until a ManagedClientConnection is got 
// from ClientConnectionRequest
private static final long MCC_TIMEOUT = 5000; /* 5 seconds */

...

HttpGet httpGet = new HttpGet(url);
setTimeouts(httpGet.getParams());

...

private static void setTimeouts(HttpParams params) {
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
        CONNECTION_TIMEOUT);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
}
10
Vit Khudenko
Thread t=new Thread()
{
  public void run()
  {
    try 
    {
      Thread.sleep(absolutetimeout);
      httpclient.getConnectionManager().closeExpiredConnections();
      httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS);
      httpclient.getConnectionManager().shutdown();
      log.debug("We shutdown the connection manager!");
    }
    catch(InterruptedException e)
    {}
  }
};

t.start();
HttpResponse res= httpclient.execute(httpget);
t.interrupt();

Est-ce que cela va dans le sens de ce que vous proposez tous?

Je ne sais pas exactement comment annuler l'exécution une fois qu'elle a commencé, mais cela a semblé fonctionner pour moi. Je ne sais pas laquelle des trois lignes du fil a fait la magie, ou si c'était une combinaison de toutes.

1
Randy Baden

J'ai rencontré le même problème, je suppose que peut-être Android ne supporte pas ce paramètre. Dans mon cas, j'ai testé les trois paramètres du ThreadSafeClientConnManager

params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );

La première et la deuxième ont bien fonctionné, mais la troisième n'a pas fonctionné comme prévu. Aucune exception n'a été levée et le thread en cours d'exécution a été bloqué indéfiniment lors de l'exécution de DefaultHttpClient # execute ().

voir http://hc.Apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
"... Vous pouvez vous assurer que le gestionnaire de connexions ne bloque pas indéfiniment l'opération de demande de connexion en définissant 'http.conn-manager.timeout' sur une valeur positive. Si la demande de connexion ne peut pas être traitée dans les limites données, laps de temps ConnectionPoolTimeoutException sera levé. "

1
Chen Zhuo

Comment faites-vous la connexion HTTP? Cela ressemble à un problème de thread. Si vous utilisez un thread d'arrière-plan, le thread peut être tué avec n'importe quel délai d'attente enregistré. Le fait que cela fonctionne la prochaine fois me dit que votre code fonctionnera si vous appelez dans un composant Android et gérez vous-même le WAKE_LOCK. Quoi qu'il en soit, s'il vous plaît poster plus d'informations sur le mécanisme d'appel?

0
uncaught_exceptions

Vous pouvez gérer vous-même les délais d'attente, de cette manière, vous pouvez être assuré que, quel que soit l'état de la connexion, à moins que vous ne receviez une réponse acceptable, votre délai d'attente se déclenche et la demande http est abandonnée.

0
Tyler

À partir de votre extrait, il n'est pas clair si vous définissez les délais d'attente avant appelant HttpClient.executeMethod(..). C'est donc ma supposition.

0
Waldheinz

Le problème peut provenir du client HTTP Apache. Voir HTTPCLIENT-1098 . Fixé dans 4.1.2.

L'exception de délai d'attente tente d'inverser DNS l'IP, à des fins de journalisation. Cela prend un temps supplémentaire jusqu'à ce que l'exception soit réellement déclenchée.

0
noam

J'ai eu des problèmes similaires avec les délais d'attente sur Android. Pour résoudre ce problème, j'ai utilisé les commandes permettant de ne pas laisser le téléphone inactif pendant que j'essayais d'établir une connexion et pendant toute lecture ou écriture sur la connexion. Cela vaut probablement le coup dans ce cas aussi.

0
S E

Eh bien, si vous restez inactif/multitâche dans une autre application, votre thread en cours d'exécution risque d'être arrêté et détruit. Peut-être devriez-vous plutôt insérer le code de connexion dans un service?

http://developer.Android.com/reference/Android/os/AsyncTask.html http://developer.Android.com/reference/Android/app/IntentService.html

0
Marius K

Bien que je n'ai pas vu cela sur la plate-forme Android, j'ai déjà vu des choses similaires sur d'autres plates-formes et la solution dans ces cas consiste à gérer le délai d'attente vous-même. Lancez un autre thread (le thread de délai d'attente) lorsque vous faites votre demande. Le thread de délai d'attente décompte le temps requis. Si le délai d'expiration expire avant que vous ne receviez des données, le thread de délai d'expiration annule la demande d'origine et vous réessayez avec une nouvelle demande. Plus difficile à coder, mais au moins vous savez que cela fonctionnera.

0
Eric Giguere