HttpClient和套接字用尽-澄清吗?

时间:2019-10-17 08:05:25

标签: c# .net httpclient .net-4.6.1

This article说,我们应该使用静态HttpClient来重用套接字。

但是第一条评论说存在DNS更改识别问题,解决方案在另一篇here中:

第二篇文章建议:

var client = new HttpClient();
client.DefaultRequestHeaders.ConnectionClose = true; 

哪个控制KeepAlive标头。 但是会妨碍您利用重新使用套接字的好处

另一个解决方案是:

var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute

但是:

他没有说我们每次发出请求时应该使用new Httpclient,还是应该使用静态请求。

问题:

说我要使用此解决方案:

var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute 
  • 我仍然应该使用static HttpClient方法吗?还是应该每次new HttpClient打电话? 还是-我应该为每个new HttpClient创建静态/非静态scheme://basedns吗?

他展示了问题,但他的结论没有给出完整的最终解决方案。

请注意-我在问.net框架。不是.net Core。

3 个答案:

答案 0 :(得分:1)

那是非常的老文章,它确实解释了为什么应该重用HttpClient,但没有解释如何处理DNS更改。 Singleton HttpClient? Beware of this serious behaviour and how to fix it中对此进行了解释。那仍然只处理一个连接。

显而易见的答案是避免单例HttpClient,但仍会重用它们一段时间。此外,不同的套接字用于连接到不同的服务器,这意味着我们确实需要在每个服务器上重用(和回收)套接字。 该解决方案后来以HttpClientFactory的形式出现。

令人高兴的是HttpClientFactory是.NET Standard 2.0程序包Microsoft.Extensions.Http ,. NET Core和.NET Old都可以使用它,而不仅仅是ASP.NET Core应用程序。例如,我在控制台应用程序中使用它。

一个很好的介绍是史蒂夫·戈登(Steve Gordon)的HttpClientFactory in ASP.NET Core 2.1 (PART 1),以及他所有在该series中的文章。

简而言之,每次我们想要HttpClient时,我们都会向工厂索要实例:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = _httpClientFactory.CreateClient();
        var result = await client.GetStringAsync("http://www.google.com");
        return Ok(result);
    }
}

HttpClient将工作委托给SocketClientHandler。那就是需要重用的东西。 HttpClientFactory产生HttpClient实例,这些实例重新使用套接字处理程序池中的套接字处理程序。处理程序会定期回收以处理DNS更改。

更好的方法是,HttpClientFactory can be combined with Polly向HttpClient实例添加重试逻辑。它通过配置处理程序在后台执行此操作。

答案 1 :(得分:0)

我认为

val helloTextView = findViewById(R.id.text_view_id) as TextView 不稳定,并且仅在Windows计算机上有效。如果您从ServicePointManager转到dotnet core,则实际上是无效代码。我不会依赖它的实现。

我的建议是创建一个仅服务dotnet framework实例的单例服务。

如果您使用的是HttpClient,它们将为您提供静态客户端的实现,并在此document

中重新描述问题

答案 2 :(得分:-1)

我自己还没有使用过它,但是我认为您可能正在寻找类似HttpClientFactoryLite的东西。它分叉了Microsoft.Extensions.HttpClientFactory,然后删除了所有“被调解”的部分(例如DI,日志记录,键入的客户端等),以删除所有外部依赖项。