2012-06-08 34 views
6

Tôi có một chuỗi công nhân nền liên tục đồng bộ hóa dữ liệu đến/từ một máy chủ từ xa. Khi tôi lần đầu tiên chạy ứng dụng, mọi thứ dường như hoạt động tốt. Nó làm cho các yêu cầu web về mỗi 30 giây và dữ liệu trả về thành công.HTTPWebRequest & Sau một thời gian, 400 (Yêu cầu Không hợp lệ) bắt đầu

Nếu tôi để mô phỏng chạy trong một thời gian dài, cuối cùng yêu cầu sẽ không thành công với Yêu cầu không hợp lệ (400). Và tất cả các yêu cầu tiếp theo cũng làm như vậy. Nếu tôi giết các ứng dụng và khởi động lại nó ... tất cả là tốt.

Bất kỳ ai có ý tưởng nào? Mã dưới đây.

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

Nó không thành công trên dòng này:

httpResponse = (HttpWebResponse)httpRequest.GetResponse(); 

Stack Trace:

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 

Yêu cầu không bao giờ nhận được đến máy chủ từ xa.

+0

** 400 ** đến từ máy chủ. Sẽ rất hữu ích nếu bạn có thể chạy một sniffer (ví dụ: wireshark) và tìm ra những gì được truyền trong trường hợp đó (và so sánh nó với phản ứng bình thường bạn nhận được trước đó). – poupou

+0

Đó là điều kỳ lạ, nó không đến từ máy chủ. IIS không bao giờ thấy yêu cầu đến. –

+0

Rất lạ - nhưng một đầu mối tốt! – poupou

Trả lời

2

Vấn đề là trong bộ sưu tập clientHeaders. Lớp RESTClient này được khởi tạo một lần trong suốt vòng đời của ứng dụng. Tôi đã thêm tiêu đề hơn và hơn và không thanh toán bù trừ chúng ra đầu tiên. Sau một thời gian, các tiêu đề đã quá lớn và một yêu cầu xấu đã được ban hành.

+1

Nó không phải dễ dàng để hiểu điều này bằng cách nhìn vào mã được cung cấp :) –

0

Tôi cho rằng bạn đã hết kết nối. Bạn có thể cố gắng tăng chúng:

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

+0

bạn có thể thử anyway để tăng kết nối. – NickD

+0

Làm cách nào để thực hiện điều đó trong MonoTouch? –

+0

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

Các vấn đề liên quan