c# - 理解正确的 http keep-alive 实现

标签 c# .net http tcp keep-alive

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

我们有一个服务器通过保持事件连接来处理 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 也不异常(exception)?

谢谢

最佳答案

我在这里和通过 Mono 代码进行了大量挖掘。 Mono 中显然存在错误。我修复了它,并将在接下来的几天内提交补丁。 RFC2616 第 8.1 节涉及持久连接。第 8.1.4 节“实际注意事项”与我们的错误相关。

引文:

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

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

关于c# - 理解正确的 http keep-alive 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33688447/

相关文章:

http - ETag header 是否使 Cache-Control header 过时?那么如何确保 Cache-Control 无害呢?

c# - 在 UWP C# 中从路径绘制图形

c# - MongoDb C# 驱动程序是否适用于 LINQ 和动态文档?

java - 从基于 Java 的应用程序访问 .NET DLL,服务包装器是否可以接受?

.net - 紧凑型框架 3.5 是否支持 System.Runtime.Serialization?

c# - WCF 是否在多个线程上运行 session ?

angularjs - 如何在angularjs中等待响应

http - 有两个?在 URL 中 - 它有效吗?

c# - 为什么 null 语句 ToString() 返回一个空字符串?

C#确认消息框在拖放过程中卡住文件资源管理器