2012-06-08 5 views
6

데이터를 원격 서버와 지속적으로 동기화하는 백그라운드 작업자 스레드가 있습니다. 처음 앱을 실행하면 모든 것이 제대로 작동하는 것처럼 보입니다. 약 30 초마다 웹 요청을하게되고 데이터가 성공적으로 반환됩니다.HTTPWebRequest & 잠시 후 400 (잘못된 요청)이 시작됩니다.

시뮬레이터를 장시간 실행하는 경우 결국 (400) 잘못된 요청으로 요청이 실패합니다. 그리고 모든 후속 요청은 똑같은 일을합니다. 내가 응용 프로그램을 죽이고 다시 시작하면 ... 모두 잘됩니다.

누구든지 아이디어가 있습니까? 코드는 다음과 같습니다.

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

그것은이 라인에 실패

httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 

스택 추적 :

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 

요청이 결코 원격 서버에 도착하지 않습니다.

+0

** 400 **은 서버에서 제공됩니다. 스니퍼 (예 : wireshark)를 실행하고 그 경우 전송 된 내용을 찾아서 (이전에받은 정상적인 응답과 비교하면) 도움이 될 것입니다. – poupou

+0

그것은 이상한 일입니다. 서버에서 오지 않습니다. IIS는 요청이 들어오는 것을 결코 보지 못합니다. –

+0

매우 이상합니다. 그러나 좋은 단서! – poupou

답변

2

문제는 clientHeaders 컬렉션이었다. 이 RESTClient 클래스는 응용 프로그램 수명주기 동안 한 번 인스턴스화됩니다. 머리글을 반복해서 추가하고 처음에 제거하지 않았습니다. 잠시 후 헤더가 너무 커져 잘못된 요청이있었습니다.

+1

제공되는 코드를 살펴보면 이해가 쉽지 않습니다. :) –

0

연결이 끊어져 있다고 가정합니다. 당신이 그들을 증가를 시도 할 수 있습니다 :

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

+0

어쨌든 연결을 늘려보십시오. – NickD

+0

MonoTouch에서 어떻게 할 수 있습니까? –

+0

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