使用.NET/C#应用程序时,我尝试从HTTP API下载数据。尽管HttpClient示例的超时设置为30分钟,但请求超时的速度会快得多。今天我了解到这是由于.NET HttpClient不发送任何TCP Keep Alive数据包。(这就是为什么我可以从Chrome中的API下载数据,正如Wireshark所证明的那样,Chrome确实发送了这些数据包,而HttpClient则没有。)
这就是我希望从API获取JSON数据的方式:
this.httpclient = new HttpClient();
[...]
result = await this.httpclient.GetAsync(url);
现在我做了一些研究,但我找不到如何发送这些保活ping。HttpClient似乎不支持它们。所以我的猜测是,当打开连接时,这些需要在套接字上启用。有什么解决办法吗,也许是避免HttpClient?我可以在套接字上以某种方式启用保活ping吗?这是一个需要通过操作系统启用的功能吗?
请注意:这不是关于HTTP“连接:Keep-Alive”报头!您可以为HttpClient类启用此功能,但由于显而易见的原因,它不会触发任何TCP Keep-Alive数据包。
编辑:x1c 0d1x当客户端发送这些Keep-Alive数据包时,请求总是有效的,否则请求将失败。这可以通过使用不同的客户端/浏览器重现。最佳示例:Postman Chrome扩展确实会发送Keep-Alive数据包,因此请求可以工作。使用几乎相同的Postman独立客户端,请求失败(或不返回任何数据),因为有趣的是,独立客户端不发送任何Keep-Alive数据包,这可以很容易地用Wireshark检查。
**编辑:**我已经找到了这个问题的一个非常简单的解决方案,请看下面我的答案。
3条答案
按热度按时间lo8azlld1#
所以现在我结束回答我自己的问题,因为我刚刚找到了一个超级简单的解决方案,实际上工作:
事实上我用了
其中baseUrl是我通过for循环发送的所有请求的公共文档根。
jm2pwxwz2#
HTTP(与WebSockets不同)不支持keepalive消息,因此我假设您指的是
SO_KEEPALIVE
样式的TCP keepalive包。即使HttpClient示例的超时设置为30分钟,请求超时的速度也会快得多。今天我了解到这是因为.NET HttpClient不发送任何TCP Keep Alive数据包。
我不认为这是正确的。发送keepalive数据包不会对超时行为产生任何影响。特别是,当keepalive到达服务器并发送ack响应时,两个应用程序甚至都没有得到通知-事实上,它们 * 不能 * 得到通知,因为TCP keepalive或ack中没有数据。
现在我做了一些研究,但我找不出如何发送这些保持活动的ping。
TCP keepalive数据包存在问题有两个原因:它们有很难设置的默认值,而且可能会被中间路由器丢弃。2这些默认值包括最少2小时的计时器,而且不能保证有能力改变它;幸运的是,现代Windows版本确实允许设置每个连接的保活计时器,并且允许将其设置为低得多的值。
也就是说,我不知道有什么方法可以到达
HttpClient
的底层Socket
。(现在)在SocketsHttpHandler
中,它实际上负责套接字连接。但是我没有看到任何API可以让你直接进入来操作套接字,或者在构造期间提供已经构造好的插座。1l5u6lss3#
这里是NetCore 2. 1以后的另一个解决方案。我发现
ServicePointManager.FindServicePoint(new Uri(url));
代码在我的情况下不起作用,这个起作用了。来源www.example.comhttps://learn.microsoft.com/en-us/dotnet/api/system.net.http.socketshttphandler.connectcallback?view=net-7.0#examples