2012-06-08 60 views
6

Tengo un hilo de trabajador de fondo que está constantemente sincronizando datos a/desde un servidor remoto. La primera vez que ejecuto la aplicación, todo parece funcionar bien. Realiza la solicitud web cada 30 segundos y los datos se devuelven correctamente.HTTPWebRequest & Después de un tiempo, 400 (Solicitud incorrecta) comienza

Si dejo el simulador en funcionamiento durante un tiempo prolongado, con el tiempo la solicitud fallará con una (400) Solicitud incorrecta. Y todas las solicitudes posteriores hacen lo mismo. Si elimino la aplicación y la reinicio ... todo está bien.

¿Alguien tiene alguna idea? El código está abajo.

public RestResponse<T> Execute<T>(RestRequest request) { 
    var restResponse = new RestResponse<T>(); 
    var serializer = new JavaScriptSerializer(); 
    var urlPath = baseUrl + "/" + request.Resource; 
    Console.WriteLine("Requesting: " + urlPath); 
    var httpRequest = (HttpWebRequest)HttpWebRequest.Create(new Uri(urlPath)); 

    httpRequest.Headers = request.Headers; 
    foreach (string key in clientHeaders.Keys) 
     httpRequest.Headers.Add(key, clientHeaders[key]); 
    httpRequest.Headers.Add("Accept-Encoding", "gzip,deflate"); 

    Authenticator.Authenticate(httpRequest); 
    httpRequest.Method = request.Method.ToString();  
    HttpWebResponse httpResponse = null; 
    try { 
     if ((request.Method == Method.POST) && (!request.IsJsonPost)) 
      SetPostData(httpRequest, request); 

     if ((request.Method == Method.POST) && (request.IsJsonPost)){ 
      SetJsonPostData(httpRequest, request); 
     } 

     httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 
     var reader = new StreamReader(GetStreamForResponse(httpResponse)); 
     var responseString = reader.ReadToEnd(); 
     Console.WriteLine(responseString); 
     reader.Close(); 
     restResponse.StatusCode = httpResponse.StatusCode; 
     restResponse.Headers = httpResponse.Headers; 
     restResponse.Data = serializer.Deserialize<T>(responseString); 
     restResponse.ResponseStatus = ResponseStatus.Completed; 
     httpResponse.Close(); 
    } catch (WebException e) { 
     restResponse.ResponseStatus = ResponseStatus.Error; 
     restResponse.ErrorMessage = e.Message; 
     restResponse.ErrorException = e; 
     var webResponse = (HttpWebResponse)e.Response; 
     if (webResponse != null) { 
      restResponse.StatusCode = webResponse.StatusCode; 
      restResponse.Headers = webResponse.Headers; 
     } 
     if (restResponse.StatusCode != HttpStatusCode.NotModified) 
      Console.WriteLine("An exception occured:\r\n " + request.Resource + "\r\n" + e + "\r\n"); 
    } catch (Exception ex) { 
     restResponse.ResponseStatus = ResponseStatus.Error; 
     restResponse.ErrorMessage = ex.Message; 
     restResponse.ErrorException = ex; 
    } 

    if (httpResponse != null) 
     httpResponse.Close(); 

    return restResponse; 
} 

Se produce un error en esta línea:

httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 

Seguimiento de la pila:

System.Net.WebException: The remote server returned an error: (400) Bad Request. 
    at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x002f2] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1477 
    at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00141] in /Developer/MonoTouch/Source/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1300 

La solicitud se nunca consiguiendo al servidor remoto.

+0

El ** 400 ** viene del servidor. Sería útil si pudiera ejecutar un rastreador (por ejemplo, wireshark) y descubrir qué se transmitió en ese caso (y compararlo con la respuesta normal que obtuvo antes). – poupou

+0

Eso es lo extraño, no viene del servidor. IIS nunca ve la solicitud entrar. –

+0

Muy raro, pero una buena pista. – poupou

Respuesta

2

El problema estaba en la colección clientHeaders. Esta clase RESTClient se crea una instancia durante el ciclo de vida de la aplicación. Estaba agregando encabezados una y otra vez y no los borraba primero. Después de un tiempo, los encabezados se volvieron demasiado grandes y se emitió una mala solicitud.

+1

No fue fácil de entender mirando el código provisto :) –

0

Supongo que se quedan sin conexiones. Se puede tratar de aumentarlos:

<configuration> <system.net> <connectionManagement> <add address="*" maxconnection="65535" /> </connectionManagement> </system.net> </configuration>

+0

puede intentarlo de todos modos para aumentar las conexiones. – NickD

+0

¿Cómo hago eso en MonoTouch? –

+0

System.Net.ServicePointManager.DefaultConnectionLimit = 65535; – NickD

Cuestiones relacionadas