2011-01-02 16 views
16

Tengo un problema cuando trato de utilizar el HttpClient que conecta a una url. La conexión http está demorando más tiempo, incluso después de configurar una conexión timeoout.http connection timeout issues

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

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

Funciona perfecto la mayor parte del tiempo. Sin embargo, de vez en cuando, la conexión http se ejecuta para siempre e ignora el setconnectiontimeout, especialmente cuando el teléfono está conectado a wifi, y el teléfono estaba inactivo.

Así que después de que el teléfono está en ralentí, la conexión http ignora el setconnectiontimeout y se ejecuta para siempre, después de cancelarlo y volver a intentarlo, funciona como un encanto cada vez. Pero esa vez que eso no funciona, crea un error threadtimeout, traté de usar un hilo diferente, funciona, pero sé que el hilo se está ejecutando durante mucho tiempo.

Entiendo que el wifi va a dormir en modo inactivo, pero no entiendo por qué está ignorando el setconnectiontimeout.

Cualquiera puede ayudar, id realmente apreciado.

+0

¿De qué plataforma está hablando? –

+0

La conexión HTTP podría "ignorar" su tiempo de espera porque realmente cree que está conectado, p. el apretón de manos inicial tuvo éxito pero nada más salió de la tubería (o en su caso, el aire). Tal vez su teléfono tenga una tendencia a seguir aceptando conexiones pero olvidándose inmediatamente de ellas cuando esté inactivo. Capturar y examinar los cuadros individuales intercambiados antes de que ocurra este problema probablemente diga mucho más. –

Respuesta

0

Puede administrar los tiempos de espera usted mismo, de esta manera puede estar seguro de que no importa en qué estado se conecte, a menos que reciba una respuesta aceptable, su tiempo de espera se disparará y se anulará la solicitud http.

+0

Antes que nada, gracias por su ayuda. Arhimed, lo intenté, no funcionó. – Mark

+0

Realicé una prueba, conecté mi teléfono a un wifi que no tiene conexión a Internet, e hice clic en la aplicación de tu tubo. tardó 30 segundos descubrir que no hay conexión, al igual que mi aplicación. Me está volviendo loco, la forma en que ignora la conexión de tiempo de espera. – Mark

+1

Eso es porque en un wifi sin acceso a internet, si su URL es un nombre de host y no una dirección IP directa, entonces la conexión ni siquiera se está haciendo; todo el tiempo que estás esperando se está gastando tratando de resolver el nombre de host. – Chochos

10

No estoy seguro si esto lo ayuda, sin embargo, creo que vale la pena compartirlo aquí. Mientras jugaba con la materia de tiempo de espera he encontrado que hay un tercer tipo de tiempo de espera puede asignar:

// 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); 
} 
+1

Android 2.01.Primero, gracias por su ayuda. Arhimed, lo intenté, pero no funcionó. El problema solo ocurre bajo una de estas condiciones: 1 - si mi teléfono está conectado a wifi, y el wifi no tiene acceso a internet. el tiempo de espera no está atrapado en este caso y toma alrededor de 30 segundos. 2_ si el teléfono está conectado a wifi y el wifi tiene acceso a internet. Después de que el teléfono ha estado funcionando al ralentí durante al menos 2 minutos, la conexión initail tarda unos 30 segundos en agotarse. Cualquier otro intento, funciona a la perfección. – Mark

+1

@Mark: si su aplicación se comporta igual que la aplicación nativa de YouTube, entonces creo que puede dormir bien (las aplicaciones nativas son codificadas por los mejores profesionales que pueden usar API tanto como sea posible). A veces hay casos que están fuera de nuestro control. Otra nota de consuelo: 30 segundos no es mucho si, por ejemplo, se compara con BlackBerry, donde tiene 2 minutos y no puede cambiar eso. ;) –

0

He tenido problemas similares con los tiempos de espera en Android. Para resolverlo, lo que hice fue utilizar los comandos para no dejar el teléfono inactivo mientras intentaba establecer una conexión y durante cualquier lectura o escritura en la conexión. Probablemente vale la pena intentarlo en este caso también.

0

Aunque no he visto esto en la plataforma Android, he visto cosas similares en otras plataformas y la solución en estos casos es administrar el tiempo de espera usted mismo. Inicia otro hilo (el hilo de tiempo de espera) cuando hagas tu pedido. El hilo de tiempo de espera cuenta regresivamente el tiempo requerido. Si el tiempo de espera expira antes de recibir datos, el hilo de tiempo de espera cancela la solicitud original y vuelve a intentar con una nueva solicitud. Más difícil de codificar, pero al menos sabes que funcionará.

0

De usted snippet no está claro si establece los tiempos de espera antes de llamando al HttpClient.executeMethod(..). Así que esta es mi suposición.

0

Bueno, si está inactivo/multitarea en otra aplicación, entonces el hilo que se está ejecutando se puede detener y destruir. Tal vez usted debe poner el código de conexión dentro de un servicio en lugar ?:

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

0

¿Cómo estás haciendo la conexión HTTP? Esto parece un problema de enhebrado. Si está utilizando un hilo de fondo, el hilo se puede matar junto con el tiempo de espera registrado. El hecho de que funcione la próxima vez me dice que su código funcionará, si realiza la llamada en un componente de Android y administra el WAKE_LOCK en él mismo. De todos modos, por favor, publique más información sobre el mecanismo de llamada?

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

¿Es eso en la línea de lo que todos ustedes están sugiriendo?

No estoy exactamente seguro de cómo cancelar la ejecución una vez que ha comenzado, pero esto pareció funcionar para mí. No estoy seguro de cuál de las tres líneas en el hilo hizo la magia, o si fue una combinación de todas ellas.

+0

En realidad, esto tampoco parece funcionar.¿Tengo que poner el ejecutar en su propio hilo, porque realmente no quiero hacer eso. ¿No hay forma de matarlo? –

1

Me he encontrado con el mismo problema, supongo que tal vez el Android no es compatible con este parámetro. En mi caso he probado todos los tres parámetros para la 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 primera y la segunda funcionó bien, pero el tercero no funcionó como se documenta. No se lanzó ninguna excepción y el hilo de ejecución se bloqueó indefinidamente cuando se ejecutaba DefaultHttpClient # execute().

ver http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
" ... Uno puede garantizar el administrador de conexión no bloquea indefinidamente en la operación de solicitud de conexión mediante el establecimiento de 'http.conn-manager.timeout' a un valor positivo. Si la solicitud de conexión no puede ser reparado dentro del período de tiempo dado, se lanzará ConnectionPoolTimeoutException ".

0

El problema podría estar en Apache HTTP Client. Ver HTTPCLIENT-1098. Solucionado en 4.1.2.

La excepción de tiempo de espera intenta invertir la dirección IP de DNS, para fines de registro. Esto lleva un tiempo adicional hasta que la excepción se active realmente.