- 它的元件包是Microsoft.Extensions.Http
- 複原HttpClient帶來的問題
1|1HttpClient相關問題
- 雖然HttpClient類實作了IDisposable,但不是首選在using語句中聲明和執行個體化它,因為釋放HttpClient對象時,基礎套接字不會立即釋放,這可能會導緻“套接字耗盡”問題 。是以,HttpClient 應進行一次執行個體化并在應用程式的生命周期中重複使用。 在負載較重的情況下,執行個體化每個請求的 HttpClient 類将耗盡可用的套接字數。 該問題會導緻 SocketException 錯誤。 要解決此問題,可能的方法是将 HttpClient 對象建立為單一對象或靜态對象,在長期運作的程序中使用 HttpClient 的共享執行個體時,開發人員遇到的另一個問題。 在将 HttpClient 執行個體化為單一執行個體或靜态對象的情況下,它無法處理 DNS 更改,但是,問題實際上不是 HttpClient 本身,而是 HttpClient 的預設構造函數,因為它建立了一個新的實際 HttpMessageHandler 執行個體,該執行個體具有上面提到的“套接字耗盡”和 DNS 更改問題 。
參考解決内容
1|2核心點
- 管理内部HttpMessageHandler的生命周期,靈活應對資源問題和DNS重新整理問題。
- 支援命名化,類型化配置,集中管理配置,避免沖突
- 靈活的出站請求管道配置,輕松管理請求生命周期
- 内置管道最外層和最記憶體日志記錄器,有Information和Trace輸出
1|3核心對象
- HttpClient
- HttpMessageHandler
- SocketsHttpHandler
- DelegatingHandler
- IHttpClientFactory
- IHttpClientBuilder
1|4使用方式
- 基本用法
- 命名用戶端模式
- 類型化用戶端模式
- 生成的用戶端
//首先,在Startup中的ConfigureService注冊我們的HttClient服務,僅僅一行代碼就可以搞定
service.AddHttpClien();
//接着,我們通過依賴注入來請求IHttpClientFactory,并建立HttpClient執行個體,以下代碼之後我們就可以放心使用HttpClient
public BasicUsageModel(IHttpClientFactory clientFactory)
{
_clientFactory = clientFactory;
}
public async Task OnGet()
var client = _clientFactory.CreateClient();
類型化用戶端
publi class XXXClient
IHttpClientFactory _httpclientFatory;
public XXXClient(IHttpClientFactory httpclientFatory)
{
_httpclientFatory=httpclientFatory;
}
public async Task<string> Get()
var client = _httpclientFatory.CreateClient();
return await client.GetStringAsync("xxx.url");
注冊
services.AddHttpClient<XXXClient>();
1|5出站請求中間件
- HttpClient具有委托處理程式概念。
建立委托處理程式
- 派生自DelegatingHandler (将 HTTP 響應消息的處理委托給另一處理程式(稱為“内部處理程式”)的 HTTP 處理程式的類型。)
- 重寫SendAsync
代碼
public class xxxHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
//處理請求
var result = await base.SendAsync(request, cancellationToken); //調用内部handler
//處理響應
return result;
}
}
public void ConfigureServices(IServiceCollection services){
services.AddSingleton<xxxHandler>();
services.AddHttpClient("XXXServiceClient", client =>
{
client.DefaultRequestHeaders.Add("client-name", "namedclient");
client.BaseAddress = new Uri("https://localhost:5003");
}).SetHandlerLifetime(TimeSpan.FromMinutes(20))
.AddHttpMessageHandler(provider => provider.GetService<xxxHandler>());
services.AddScoped<xxxHandler>();
public class XXXServiceClient
IHttpClientFactory _httpClientFactory;
const string _clientName = "NamedOrderServiceClient"; //定義用戶端名稱
public XXXServiceClient(IHttpClientFactory httpClientFactory)
_httpClientFactory = httpClientFactory;
public async Task<string> Get()
var client = _httpClientFactory.CreateClient(_clientName); //使用用戶端名稱擷取用戶端
//使用client發起HTTP請求,這裡使用相對路徑來通路
return await client.GetStringAsync("/OrderService");
1|6生命周期
- 每次對 IHttpClientFactory 調用 CreateClient 都會傳回一個新 HttpClient 執行個體。 每個命名用戶端都建立一個 HttpMessageHandler。 工廠管理 HttpMessageHandler 執行個體的生存期。
- 處理程式的預設生存期為兩分鐘,可通過SetHandlerLifetime 重新設定。