我正在使用.NET System.Net.Http.HttpClient
试验Heroku API。特别是,我希望keep-alive
能够工作,以便我可以使用一个TCP连接发送许多HTTP请求,并且只进行一次SSL握手,而不是使用每次请求的SSL握手设置TCP连接。
我正在测试https://api.heroku.com/status,它提供了一个不错的HTTP 200,并使用Wireshark来监控TCP流量。
谷歌浏览器,ApacheBench(带有-k
标志)和curl似乎都能够保持TCP连接打开并发送多个请求。 HttpClient,不是那么多。我还针对其他主机(例如https://google.com/)测试了HttpClient,在那里我只看到一个SSL握手/ TCP设置。所以看起来这是HttpClient和Heroku API之间的不良交互。
以下是我正在测试的代码:
private static async void TestUrl(string url)
{
using (var client = GetClient())
{
await client.GetAsync(url);
await client.GetAsync(url);
await client.GetAsync(url);
await client.GetAsync(url);
}
}
private static HttpClient GetClient()
{
var requestHandler = new HttpClientHandler
{
UseCookies = false,
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip,
};
return new HttpClient(requestHandler);
}
我还附上了一个Wireshark屏幕截图,显示了HttpClient在接收到数据后立即决定重置(RST
)连接。
对于这里发生了什么有任何建议吗?
答案 0 :(得分:6)
使用 WebRequestHandler 类而不是 HttpClientHandler 并将属性HttpWebRequest.UnsafeAuthenticatedConnectionSharing 设置为True。
答案 1 :(得分:0)
某些代理服务器在进行身份验证时会忽略keep-alive。如果我没记错的话,那就是代理服务器使用NTLM身份验证的时候。
过去,我必须添加一个部分类来“帮助”一些Web服务代理类。
我用
覆盖了GetWebRequest(Uri uri)方法System.Net.HttpWebRequest webRequest =
(System.Net.HttpWebRequest)base.GetWebRequest(uri);
webRequest.ProtocolVersion = HttpVersion.Veraion10; // I know this is strange, but it works
webRequest.ServicePoint.Expect100Continue = false; // This is where the magic lives
return webRequest;