请使用IHttpClientFactory代替直接创建HttpClient

作者 the7
发布于 2020年02月13日
评论 0
浏览 193

直接实例创建HttpClient,当然是可以。问题就出在,当遇到频繁访问的时候,会导致Socket耗尽。即便用using语法包一层,但在调用Dispose方法时,连接并不会立即释放,如果遇到频繁访问,依然存在Socket耗尽的问题,所以,微软推荐用IHttpClientFactory来创建HttpClient

基本使用

在启动方法中使用AddHttpClient来注册IHttpClientFactory

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient();

在需使用的地方

public class TestController:Controller
{
   private readonly IHttpClientFactory _httpClientFactory;
   public TestController(IHttpClientFactory httpClientFactory)
   {
      _httpClientFactory = httpClientFactory;
   }
   public IActionResult Home()
   {
      var client = _clientFactory.CreateClient();
	  ...
   }
}

命名化 HttpClient

有时候项目中可能会用到多个client,每个client也需要不同的配置,比如做爬虫你可能要带上Cookie信息,诸如此类的需求,这时候我们就可以使用命名化HttpClient。

services.AddHttpClient("github", c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    // Github API versioning
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    // Github requires a user-agent
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

在需使用的地方

public class TestController:Controller
{
   private readonly IHttpClientFactory _httpClientFactory;
   public TestController(IHttpClientFactory httpClientFactory)
   {
      _httpClientFactory = httpClientFactory;
   }
   public IActionResult Home()
   {
      var client = _clientFactory.CreateClient("github");
	  ...
   }
}

类型化 HttpClient

启动类中注册

services.AddHttpClient<TestService>();//普通注册

services.AddHttpClient<Test1Service>(c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
}); // 配置

在需要使用的地方

public class TestService
{
   private readonly HttpClient _httpClient;
   public TestService(HttpClient httpClient)
   {
      _httpClient = httpClient;
   }
   public IActionResult Home()
   {
      var client = _httpClient;
	  ...
   }
}

单例或静态使用

在stackoverflow上也看到,有人把 HttpClient 做成单例或直接设为静态字段的,其实我觉得也是可以的,微软官方文档上也写着

But there’s a second issue with HttpClient that you can have when you use it as singleton or static object. In this case, a singleton or static HttpClient doesn't respect DNS changes, as explained in this issue at the dotnet/corefx GitHub repository.

只是不能监测DNS变动,如果你能确保DNS不变,那么是可以用静态或单例的,个人觉得。

4条评论

  • 念往昔丶繁华竞逐

    2019年5月20日

    最后一个五官很漂亮,虽然脸稍微大了一点点,但也算普通人里漂亮的
  • Eleven

    2019年5月20日

    念往昔丶繁华竞逐:
    最后一个五官很漂亮,虽然脸稍微大了一点点,但也算普通人里漂亮的...
    这帖子真的是精品。美中不足的是,为什么要用繁体,虽然能看懂,但有些麻烦呀。
  • SukiU

    2019年5月20日

    我曾在某外企互联网公司工作过一段时间,他们就是那种工作时间聊天摸鱼,下班时间拼命工作,然后加班蹭加班费和补贴😂
微信公众号
站长帮
微信公众号,每日更新!