IHttpClientFactory是什么?为什么出现了IHttpClientFactory
一、IHttpClientFactory是什么?
IHttpClientFactory是.netcore2.1才开始引入的,是HttpClient的工厂接口,它为我们提供了获取HttpClient的接口,它帮助我们维护HttpClient的生命周期。当我们需要HttpClient访问网络时,它会自动帮我们获取或者是创建HttpClient(存在空闲的HttpClient时,直接提供;当不存在可用的HttpClient时自动创建)。它相当于HttpClient池。
二、为什么出现IHttpClientFactory?
传统的HttpClient创建后,其占用了Socket资源并且其不会是及时的回收。我们每次new一个HttpClient时是一个全新的对象,所以在高并发下又是会导致socket资源耗尽(Unable to connect to the remote serverSystem.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.)。而如果采用单例或者静态的HttpClient,却达不到高效的使用网络请求,而且当访问不同的url时,单例或者静态的HttpClient往往会导致访问混乱而出现错误。
.NetCore简单封装基于IHttpClientFactory的HttpClient请求
1 public class HttpWebClient 2 { 3 4 private IHttpClientFactory _httpClientFactory; 5 public HttpWebClient(IHttpClientFactory httpClientFactory) 6 { 7 this._httpClientFactory = httpClientFactory; 8 } 9 /// <summary> 10 /// Get请求 11 /// </summary> 12 /// <param name="url"></param> 13 /// <param name="dicHeaders"></param> 14 /// <param name="timeoutSecond"></param> 15 /// <returns></returns> 16 //public async Task<string> GetAsync(string url, int timeoutSecond = 120) 17 //{ 18 // var client = _httpClientFactory.CreateClient(); 19 // #region 最好不要这样绑定header, 20 // //DefaultRequestHeaders是和httpClient绑定的,当完成当前请求后,其它请求从factory中获取时,还是会有绑定的header的 21 // //会造成错误 22 // //if (dicHeaders != null) 23 // //{ 24 // // foreach (var header in dicHeaders) 25 // // { 26 // // client.DefaultRequestHeaders.Add(header.Key, header.Value); 27 // // } 28 // //} 29 // #endregion 30 // client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 31 // var response = await client.GetAsync(url); 32 // var result = await response.Content.ReadAsStringAsync(); 33 // return result; 34 //} 35 36 37 38 39 /// <summary> 40 /// Get异步请求 41 /// </summary> 42 /// <param name="url"></param> 43 /// <param name="dicHeaders"></param> 44 /// <param name="timeoutSecond"></param> 45 /// <returns></returns> 46 public async Task<string> GetAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond = 120) 47 { 48 var client = _httpClientFactory.CreateClient(); 49 var request = new HttpRequestMessage(HttpMethod.Get, url); 50 if (dicHeaders != null) 51 { 52 foreach (var header in dicHeaders) 53 { 54 request.Headers.Add(header.Key, header.Value); 55 } 56 } 57 client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 58 var response = await client.SendAsync(request); 59 if (response.IsSuccessStatusCode) 60 { 61 var result = await response.Content.ReadAsStringAsync(); 62 return result; 63 } 64 else 65 { 66 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 67 68 } 69 } 70 /// <summary> 71 /// 72 /// </summary> 73 /// <param name="url"></param> 74 /// <param name="requestString"></param> 75 /// <param name="dicHeaders"></param> 76 /// <param name="timeoutSecond"></param> 77 /// <returns></returns> 78 public async Task<string> PostAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond) 79 { 80 var client = _httpClientFactory.CreateClient(); 81 var requestContent = new StringContent(requestString); 82 if (dicHeaders != null) 83 { 84 foreach (var head in dicHeaders) 85 { 86 requestContent.Headers.Add(head.Key, head.Value); 87 } 88 } 89 client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 90 var response = await client.PostAsync(url, requestContent); 91 if (response.IsSuccessStatusCode) 92 { 93 var result = await response.Content.ReadAsStringAsync(); 94 return result; 95 } 96 else 97 { 98 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 99 } 100 } 101 /// <summary> 102 /// 103 /// </summary> 104 /// <param name="url"></param> 105 /// <param name="requestString"></param> 106 /// <param name="dicHeaders"></param> 107 /// <param name="timeoutSecond"></param> 108 /// <returns></returns> 109 public async Task<string> PutAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond) 110 { 111 var client = _httpClientFactory.CreateClient(); 112 var requestContent = new StringContent(requestString); 113 if (dicHeaders != null) 114 { 115 foreach (var head in dicHeaders) 116 { 117 requestContent.Headers.Add(head.Key, head.Value); 118 } 119 } 120 client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 121 var response = await client.PutAsync(url, requestContent); 122 if (response.IsSuccessStatusCode) 123 { 124 var result = await response.Content.ReadAsStringAsync(); 125 return result; 126 } 127 else 128 { 129 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 130 } 131 } 132 133 /// <summary> 134 /// Patch异步请求 135 /// </summary> 136 /// <param name="url"></param> 137 /// <param name="requestString"></param> 138 /// <param name="dicHeaders"></param> 139 /// <param name="timeoutSecond"></param> 140 /// <returns></returns> 141 public async Task<string> PatchAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond) 142 { 143 var client = _httpClientFactory.CreateClient(); 144 var requestContent = new StringContent(requestString); 145 if (dicHeaders != null) 146 { 147 foreach (var head in dicHeaders) 148 { 149 requestContent.Headers.Add(head.Key, head.Value); 150 } 151 } 152 client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 153 var response = await client.PatchAsync(url, requestContent); 154 if (response.IsSuccessStatusCode) 155 { 156 var result = await response.Content.ReadAsStringAsync(); 157 return result; 158 } 159 else 160 { 161 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 162 } 163 } 164 public async Task<string> DeleteAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond) 165 { 166 var client = _httpClientFactory.CreateClient(); 167 var request = new HttpRequestMessage(HttpMethod.Delete, url); 168 if (dicHeaders != null) 169 { 170 foreach (var head in dicHeaders) 171 { 172 request.Headers.Add(head.Key, head.Value); 173 } 174 } 175 client.Timeout = TimeSpan.FromSeconds(timeoutSecond); 176 var response = await client.SendAsync(request); 177 if (response.IsSuccessStatusCode) 178 { 179 var result = await response.Content.ReadAsStringAsync(); 180 return result; 181 } 182 else 183 { 184 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 185 } 186 } 187 /// <summary> 188 /// 异步请求(通用) 189 /// </summary> 190 /// <param name="url"></param> 191 /// <param name="method"></param> 192 /// <param name="requestString"></param> 193 /// <param name="dicHeaders"></param> 194 /// <param name="timeoutSecond"></param> 195 /// <returns></returns> 196 public async Task<string> ExecuteAsync(string url, HttpMethod method, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond = 120) 197 { 198 var client = _httpClientFactory.CreateClient(); 199 var request = new HttpRequestMessage(method, url) 200 { 201 Content = new StringContent(requestString), 202 }; 203 if (dicHeaders != null) 204 { 205 foreach (var header in dicHeaders) 206 { 207 request.Headers.Add(header.Key, header.Value); 208 } 209 } 210 var response = await client.SendAsync(request); 211 if (response.IsSuccessStatusCode) 212 { 213 var result = await response.Content.ReadAsStringAsync(); 214 return result; 215 } 216 else 217 { 218 throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}"); 219 } 220 } 221 222 }
CustomerHttpException类的简单定义
public class CustomerHttpException : Exception { public CustomerHttpException() : base() { } public CustomerHttpException(string message) : base(message) { } }