ASP.Net Core 是一個開源的,跨平臺的,輕量級模塊化框架,可用它來構建高性能的Web程序,這篇文章我們將會討論如何在 ASP.Net Core 中使用 HttpClientFactory。
爲什麼要使用 HttpClientFactory
可以用 HttpClientFactory 來集中化管理 HttpClient,工廠提供了對 HttpClient 的創建,配置和調度,值得一提的是:HttpClient 一直都是 Http 請求業務方面的一等公民。
HttpClient 雖好,但它有一些缺點:
-
創建太多的 HttpClient 是一種低效的行爲,因爲當一個新客戶端連接到遠程 Server 時,你的應用程序還需要承擔着重連遠程 Server 的開銷。
-
如果每一個 request 都創建一個 HttpClient,當應用程序負載過大, Socket 必將耗盡,比如默認情況下 HttpClient 會維持至少4分鐘的 Connection 連接。
所以推薦的做法是創建一個可供複用的共享式 HttpClient 實例,如果你要打破沙鍋問到低的話,即使是創建共享式的 HttpClient 也會有很多問題,比如它會無視 DNS 緩存生效,那怎麼辦呢?可以用 .NET Core 2.1 引入的 HttpClientFactory 來解決此問題。。。用它來統一化的高效管理 HttpClient。
使用 HttpClientFactory
HttpClientFactory 有兩種使用方式。
-
NamedClient -
TypedClient
所謂的 NamedClient 就是註冊帶有標記的 HttpClient 到 HttpClientFactory 工廠中,下面的代碼展示了一個名爲 IDGCustomApi
的 HttpClient 的工廠註冊。
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("IDGCustomApi", client =>
{
client.BaseAddress = new Uri("https://localhost:6045/");
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("User-Agent", "IDG");
});
services.AddControllers();
}
所謂的 TypedClient 就是註冊一個你自定義的 HttpClient,我想你肯定有點懵逼了,沒關係,我現在就來自定義 HttpClient, 然後通過 AddHttpClient()
註冊到容器中。
public class CustomHttpClient
{
public HttpClient Client { get; }
public CustomHttpClient(HttpClient client)
{
Client = client;
}
}
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<CustomHttpClient>(client => client.BaseAddress = new Uri("https://localhost:6045/"));
services.AddControllers();
}
}
注入 Controller
爲了能夠在 Controller 中使用,可以將 IHttpClientFactory 通過構造函數方式進行注入,參考如下代碼:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private IHttpClientFactory httpClientFactory;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
[HttpGet]
public async Task<string> Get()
{
var httpClient = httpClientFactory.CreateClient("IDGCustomApi");
string html = await httpClient.GetStringAsync("http://bing.com");
return html;
}
}
從 IHttpClientFactory 的默認實現 DefaultHttpClientFactory 的源碼也可以看出,httpClient 所關聯的 HttpMessageHandler 和 Options 都被工廠跟蹤和管控。
internal class DefaultHttpClientFactory : IHttpClientFactory, IHttpMessageHandlerFactory
{
public HttpClient CreateClient(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
HttpMessageHandler handler = CreateHandler(name);
HttpClient httpClient = new HttpClient(handler, disposeHandler: false);
HttpClientFactoryOptions httpClientFactoryOptions = _optionsMonitor.Get(name);
for (int i = 0; i < httpClientFactoryOptions.HttpClientActions.Count; i++)
{
httpClientFactoryOptions.HttpClientActions[i](httpClient);
}
return httpClient;
}
public HttpMessageHandler CreateHandler(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
ActiveHandlerTrackingEntry value = _activeHandlers.GetOrAdd(name, _entryFactory).Value;
StartHandlerEntryTimer(value);
return value.Handler;
}
}
譯文鏈接:https://www.infoworld.com/article/3276007/how-to-work-with-httpclientfactory-in-aspnet-core.html
本文分享自微信公衆號 - 一線碼農聊技術(dotnetfly)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。