我需要尝试修复 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/