理解正确的http keep-alive实现

时间:2015-11-13 08:24:25

标签: c# .net http tcp-ip keep-alive

我需要尝试修复Mono中的错误。多年来,该报告已经被报道,人们试图找出解决方案。在我的情况下,只要有一些延迟,它就很容易重现。我或许可以解决问题,但首先我必须了解正确的行为。

我们有一台服务器通过keep-alive连接提供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,时间设置为达到服务器限制,此测试都会抛出异常。 Mono实现归结为WebConnection :: ReadDone,它调用Stream :: ReadDone。 Stream :: ReadDone显然理解服务器发送的FIN数据包意味着流已关闭并返回0。 WebConnection :: ReadDone将此解释为错误并立即抛出异常。

什么是正确的行为?为什么.NET没有例外?

谢谢

1 个答案:

答案 0 :(得分:0)

我在这里和通过Mono代码做了一堆挖掘。 Mono中显然存在一个错误。我修好了,并在接下来的几天内提交补丁。 RFC2616第8.1节涉及持久连接。第8.1.4节"实际考虑因素"与我们的bug有关。

引用:

客户端,服务器或代理可以随时关闭传输连接。 ...客户端,服务器和代理必须能够从异步关闭事件中恢复。客户端软件应该重新打开传输连接并重新传输请求的中止序列而无需用户交互,只要请求序列是幂等的(参见第9.1.2节)......

我的补丁根据RFC

检查连接是否保持活动并尝试恢复