连接保持不特定的主机正在与System.Net.Http.HttpClient在与、主机、System、HttpClient

2023-09-03 00:53:47 作者:下面给你吃

我尝试用使用.NET System.Net.Http.HttpClient Heroku的API。我特别想保活来工作,这样我可以使用一个TCP连接发送的HTTP请求,只做一SSL握手,而不是设置使用SSL的TCP连接每次请求握手。

I'm experimenting with the Heroku API using the .NET System.Net.Http.HttpClient. In particular, I want keep-alive to work so that I can send many HTTP requests using one TCP connection and only do one SSL handshake instead of setting up a TCP connection with SSL handshakes per request.

我测试对 https://api.heroku.com/status 这给出了一个很好的HTTP 200,并用Wireshark来监视TCP流量。

I'm testing against https://api.heroku.com/status which gives a nice HTTP 200, and using Wireshark to monitor TCP traffic.

谷歌浏览器,ApacheBench(与 -k 标记)和卷曲似乎都能够保持一个TCP连接开放和发送多个请求。 HttpClient的,没有这么多。我还测试的HttpClient对其他主机(如 https://google.com/ 并在那里我只能检测到一个SSL握手/ TCP设置。如此看来喜欢它的之间的HttpClient和Heroku的API不好的互动。

Google Chrome, ApacheBench (with -k flag) and curl all seem to be able to keep a TCP connection open and send multiple requests. HttpClient, not so much. I have also tested HttpClient against other hosts (eg. https://google.com/ and there I only see one SSL handshake/TCP setup. So it seems like it's a bad interaction between HttpClient and the Heroku API.

这里的code我与测试:

Here's the code I'm testing with:

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 )的连接。

什么是怎么回事有什么建议?

Any suggestions for what's going on here?

推荐答案

使用的 WebRequestHandler 的类取代的 HttpClientHandler 的并设置属性 HttpWebRequest.UnsafeAuthenticatedConnectionSharing 为True。

Use WebRequestHandler class instead of HttpClientHandler and set property HttpWebRequest.UnsafeAuthenticatedConnectionSharing to True.