【问题标题】:understanding correct http keep-alive implementation理解正确的 http keep-alive 实现
【发布时间】:2016-02-14 18:44:48
【问题描述】:

我需要尝试修复 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 也不例外?

谢谢

【问题讨论】:

  • 我查看了 .NET 内部结构。看来,.NET 使用 WinHttp DLL 来执行传输。尽管如此,内部还是不明白发生了什么。

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


【解决方案1】:

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

引用:

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

我的补丁会根据 RFC 检查连接是否保持活动状态并尝试恢复

【讨论】:

    猜你喜欢
    • 2014-01-12
    • 2012-09-15
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多