2015-11-13 41 views
1

我需要嘗試修復Mono中的錯誤。這個錯誤已經有報道,人們多年來一直試圖找出解決方案。在我的情況下,只要存在一些延遲,就很容易重現。我可能能夠解決這個問題,但首先我必須明白什麼纔是正確的行爲。瞭解正確的http保持活動實施

我們有一臺服務器通過保持活動連接提供http請求。連接被配置爲在服務器關閉連接之前有超時和服務請求限制。

一個簡單的測試使用.NET/Mono HttpClient :: GetASync(uri)方法定期發出請求。

while (true) 
    { 
     try 
     { 
      var httpResponse = await httpClient.GetAsync("https://192.168.1.22/api/v1/system/status/", cancellationToken); 
      if (httpResponse.IsSuccessStatusCode) 
      { 
       Console.Write("."); 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("HttpClientGetStatus- Exception - " + ex.GetType() + " " + ex.Message); 
     } 
     Thread.Sleep(this.StatusFreq * 1000); 
    } 

在Microsoft .NET上,它工作正常。在Mono上,無論是Windows/Linux/OSX,在計時設置達到服務器限制時,此測試都會引發異常。單聲道實現歸結爲WebConnection :: ReadDone,它調用Stream :: ReadDone。 Stream :: ReadDone顯然理解服務器發送的FIN數據包意味着該流已關閉,並返回0。 WebConnection :: ReadDone將其解釋爲錯誤,並立即引發異常。

什麼是正確的行爲?爲什麼.NET沒有例外?

謝謝

+0

我看穿了.NET的內部。看來,.NET使用WinHttp DLL來執行傳輸。儘管如此,內部並不瞭解發生了什麼。 –

回答

0

我做了一堆挖掘,在這裏,通過單聲道代碼。 Mono中有一個明顯的錯誤。我修好了,並會在接下來的幾天內提交補丁。 RFC2616第8.1節涉及持久連接。第8.1.4節「實際考慮事項」與我們的錯誤有關。

引文:

客戶端,服務器,或代理可能在任何時候關閉傳輸連接。 ...客戶端,服務器和代理必須能夠從異步關閉事件中恢復。客戶端軟件應該重新打開傳輸連接,並在沒有用戶交互的情況下重新傳輸中止的請求序列,只要請求序列是冪等的(請參閱第9.1.2節)...

我的補丁檢查連接是否保持活動狀態,嘗試恢復,根據RFC