2015-11-13 2 views
1

Мне нужно попытаться исправить ошибку в Mono. Сообщалось об ошибке, и люди пытались найти решение в течение многих лет. В моей ситуации он легко воспроизводится, если есть некоторое время ожидания. Я мог бы решить проблему, но сначала я должен понять, что будет правильным поведением.понимание правильной реализации http keep-alive

У нас есть сервер, обслуживающий HTTP-запросы по каналам keep-alive. Соединения настроены так, чтобы иметь тайм-аут и предел запросов, которые были выполнены до того, как соединение будет закрыто сервером.

Простой тест периодически выдает запросы с использованием метода .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, с установленным временем для ограничения сервера, этот тест выдает исключение. Реализация Mono сводится к WebConnection :: ReadDone, которая вызывает Stream :: ReadDone. Stream :: ReadDone, по-видимому, понимает, что пакет FIN, посланный сервером, означает, что поток был закрыт и возвращает 0, как следует. WebConnection :: ReadDone интерпретирует это как ошибку и немедленно выдает исключение.

Что было бы правильного поведения? Почему нет исключений из .NET?

Спасибо

+0

Я просмотрел внутренние компоненты .NET. Похоже, .NET использует WinHttp DLL для выполнения переноса. Тем не менее, не понимал, что происходит внутри. –

ответ

0

Я сделал кучу копать, здесь и через код Mono. В Mono явно есть ошибка. Я исправил его и отправил патч в ближайшие несколько дней. Раздел 8.1 RFC2616 касается постоянных соединений. Раздел 8.1.4 «Практические соображения» относится к нашей ошибке.

Образец цитирования:

клиент, сервер или прокси-сервер может закрыть транспортное соединение в любое время. ... клиенты, серверы и прокси должны ДОЛЖНЫ быть в состоянии восстанавливаться после асинхронных событий закрытия. Клиентское ПО ДОЛЖНО повторно открыть транспортное соединение и повторно передать отмененную последовательность запросов без взаимодействия с пользователем, если последовательность запросов является идемпотентной (см. Раздел 9.1.2) ...

Мой патч проверяет, поддерживается ли соединение, и пытается восстановить, согласно RFC

Смежные вопросы