Asp.Net Core2.1前后使用HttpClient的兩種方式
前言
在.Net Core應(yīng)用開發(fā)中,調(diào)用第三方接口也是常有的事情,HttpClient使用人數(shù)、使用頻率算是最高的一種了,在.Net Core中,HttpClient的使用方式隨著版本的升級(jí)也發(fā)生了一些變化,本次就講解一下Asp.Net Core2.1前后使用的兩種方式。
一、原先HttpClient使用方式
一般來(lái)講,喜歡要用的時(shí)候才會(huì)選擇去獲取資源,因此,當(dāng)在有需求時(shí)才會(huì)用HttpClient去調(diào)用資源,便會(huì)使用如下這種方式或其它方式獲取資源。
//do something... using (var httpClient = new HttpClient()) { var requestUri = "http://aspnetcore.online/api/resource/getresource"; var httpResponseMessage = await httpClient.GetAsync(requestUri); //do something... return Ok(httpResponseMessage); }
如果可以正常訪問(wèn)目標(biāo)地址的話,則會(huì)返回相應(yīng)的資源信息?! ?/p>
又如Post方式提交并返回相應(yīng)的內(nèi)容,都是可以直接使用。
//do something... using (var httpClient = new HttpClient()) { var requestUri = "http://aspnetcore.online/api/resource/postresource"; var httpResponseMessage = await httpClient.PostAsJsonAsync(requestUri,"星城軟件"); //do something... return Ok(httpResponseMessage); }
但是這種情況下會(huì)出現(xiàn)一個(gè)嚴(yán)重的問(wèn)題,在不停的調(diào)用情形下,tcp連接數(shù)會(huì)被耗盡,雖然使用using方式調(diào)用HttpClient并在退出前調(diào)用Dispose()方法將HttpClient釋放了,但是tcp連接仍然處于保持狀態(tài),在240s后才會(huì)自動(dòng)斷開,這里就涉及到一個(gè)連接狀態(tài)了,首先得理解下http的工作原理,http協(xié)議是建立在tcp協(xié)議基礎(chǔ)之上,當(dāng)瀏覽器需要從服務(wù)器獲取數(shù)據(jù)的時(shí)候,會(huì)發(fā)出一次http請(qǐng)求。http會(huì)通過(guò)tcp建立起一個(gè)到服務(wù)器的連接通道,當(dāng)本次請(qǐng)求需要的數(shù)據(jù)完畢后,http會(huì)立即將tcp連接斷開,這個(gè)過(guò)程是很短的。所以http連接是一種短連接,是一種無(wú)狀態(tài)的連接。但是tcp的連接只要我們不通過(guò)代碼把連接關(guān)閉,這個(gè)連接就會(huì)在客戶端和服務(wù)端的進(jìn)程中一直存在,相關(guān)狀態(tài)數(shù)據(jù)會(huì)一直保存著,直到無(wú)響應(yīng)狀態(tài)持續(xù)了默認(rèn)關(guān)閉時(shí)間后自動(dòng)斷開。
當(dāng)短期請(qǐng)求量過(guò)大時(shí),這就可能導(dǎo)致了"套接字資源耗盡異常",因此,為了解決這個(gè)問(wèn)題,想到不釋放HttpClient,將它作為單例一直使用,實(shí)現(xiàn)單例方式有很多種。
如使用單例模式,只生成一個(gè)HttpClient
private static HttpClient _httpClient = null; public HttpClient CreateHttpClient() { if (_httpClient == null) _httpClient = new HttpClient(); return _httpClient; }
亦或是在初始化時(shí)完成單例注入,創(chuàng)建一個(gè)IHttpClient接口,及相應(yīng)的實(shí)現(xiàn)StandardHttpClient,實(shí)現(xiàn)類種加入HttpClient屬性,在實(shí)現(xiàn)類構(gòu)造函數(shù)中完成初始化后便可直接使用該實(shí)現(xiàn)類完成資源請(qǐng)求工作。
//在startup中完成單例注入 services.AddSingleton<IHttpClient, StandardHttpClient>(); public interface IHttpClient { //do something } public class StandardHttpClient : IHttpClient { private HttpClient _client; public StandardHttpClient() { _client = new HttpClient(); } //do something... }
雖然這樣解決了"套接字資源耗盡異常",但是又帶來(lái)了新的問(wèn)題,熬不過(guò)DNS生存時(shí)間(TTL),當(dāng)主機(jī) DNS 更新時(shí),又可能產(chǎn)生異常,提示無(wú)法解析主機(jī)名稱,因?yàn)閱卫鼿ttpClient不會(huì)隨著主機(jī)DNS更新而更新,Singleton HttpClient doesn't respect DNS changes。
An error occurred while sending the request. Couldn't resolve host name An error occurred while sending the request. Couldn't resolve host name
二、現(xiàn)有HttpClient使用方式
在.Net Core2.1后,微軟引入了HttpClientFactory徹底解決這個(gè)問(wèn)題,工廠模式的職責(zé)是負(fù)責(zé)創(chuàng)建對(duì)象,這個(gè)類主要負(fù)責(zé)創(chuàng)建HttpClient實(shí)例
首先在StartUp中注冊(cè),可能會(huì)提示安裝這個(gè)Nuget包
services.AddHttpClient();
該方法內(nèi)部實(shí)現(xiàn)過(guò)程可以瀏覽:http://www.dbjr.com.cn/article/157254.htm
其次,在需要使用時(shí),使用構(gòu)造函數(shù)注入即可
[Route("api/[controller]")] [ApiController] public class HttpClientController : ControllerBase { IHttpClientFactory _httpClientFactory; public HttpClientController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } [HttpGet] [Route(nameof(Index))] public async Task<IActionResult> Index() { var client = _httpClientFactory.CreateClient(); var result = await client.GetAsync("http://aspnetcore.online/api/resource/getresource"); return Ok(result); } }
具體實(shí)現(xiàn)原理簡(jiǎn)述為:HttpClientFactory內(nèi)部管理著一個(gè)連接句柄池,對(duì)每一個(gè)HttpClient使用一個(gè)句柄進(jìn)行跟蹤管理,當(dāng)該實(shí)例使用完畢后,句柄仍然控制資源釋放,在短期大量處理時(shí),可以將這部分句柄完成對(duì)不同實(shí)例的跟蹤管理,使得句柄,也就是相應(yīng)的套接字生命周期延長(zhǎng),對(duì)套接字完成了復(fù)用。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- ASP.NET Core 文件響應(yīng)壓縮的常見使用誤區(qū)
- ASP.NET Core中的響應(yīng)壓縮的實(shí)現(xiàn)
- asp.net core為IHttpClientFactory添加動(dòng)態(tài)命名配置
- 如何在ASP.NET Core中使用HttpClientFactory
- 在ASP.NET Core中用HttpClient發(fā)送POST, PUT和DELETE請(qǐng)求
- .NET CORE HttpClient的使用方法
- .NET Core使用HttpClient進(jìn)行表單提交時(shí)遇到的問(wèn)題
- .Net Core下HTTP請(qǐng)求IHttpClientFactory示例詳解
- ASP.NET Core針對(duì)一個(gè)使用HttpClient對(duì)象的類編寫單元測(cè)試詳解
- .NET Core中HttpClient的正確打開方式
- .NET Core中使用HttpClient的正確姿勢(shì)
- .NET Core 2.1中HttpClientFactory的最佳實(shí)踐記錄
- .Net Core HttpClient處理響應(yīng)壓縮詳細(xì)
相關(guān)文章
DataList中TextBox onfocus調(diào)用后臺(tái)void靜態(tài)方法及獲取相應(yīng)行數(shù)
DataList中我放了一個(gè)TextBox 現(xiàn)在的問(wèn)題是當(dāng)我光標(biāo)放到TextBox上的時(shí)候。如果讓onfocus調(diào)用后臺(tái)某一個(gè)void靜態(tài)方法并且在靜態(tài)方法里邊獲取光標(biāo)相應(yīng)的DataList的相應(yīng)行數(shù),本文介紹如何實(shí)現(xiàn),感興趣的朋友可以了解下2013-01-01ASP.NET2.0服務(wù)器控件之自定義狀態(tài)管理
ASP.NET2.0服務(wù)器控件之自定義狀態(tài)管理...2006-09-09.NET Core Dapper操作mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法
這篇文章主要介紹了.NET Core Dapper操作mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04asp.net多選項(xiàng)卡頁(yè)面的創(chuàng)建及使用方法
看了很多朋友還不會(huì)創(chuàng)建多選項(xiàng)卡的頁(yè)面,特地總結(jié)了一下用法,看一遍就會(huì)了,感興趣的朋友可以參考下2013-01-01ASP.NET中的DataGridView綁定數(shù)據(jù)和選中行刪除功能具體實(shí)例
廢話就不多說(shuō)了,都說(shuō).NET是托控件的,我就托給你們看,這個(gè)博文主要講 DataGridView 的數(shù)據(jù)綁定,和選中行刪除功能2013-12-12CheckBox為CheckBoxList實(shí)現(xiàn)全選或全取消選擇(js代碼實(shí)現(xiàn))
在管理商品后臺(tái)是,由于CheckBoxList的選擇太多,用戶需要一個(gè)全選或全取消的功能,這樣操作起來(lái)會(huì)提高效率同時(shí)可以減少誤點(diǎn)等,本文將教大家如何實(shí)現(xiàn),有需要的朋友可以參考下,望本文對(duì)你有所幫助2013-01-01通過(guò).NET 6實(shí)現(xiàn)RefreshToken
當(dāng)獲取到的Token過(guò)期以后,我們必須要重新請(qǐng)求認(rèn)證接口以獲取新的Token,為了提升用戶體驗(yàn),我們一般會(huì)利用Refresh Token功能,本文將具體為大家介紹一下如何實(shí)現(xiàn)Refresh Token,感興趣的可以學(xué)習(xí)一下2022-01-01