HttpClient问题
- HttPClient使用完之后不会立即关闭开启网络连接时会占用底层socket资源,但在HttpClient调用其本身的Dispose方法时,并不能立刻释放该资源
如果频繁的使用HttpClient,频繁的打开链接,关闭链接消耗就会很大
HttpClientFactory
在.NET Core 2.1版本之后引入的 HttpClientFactory解决了HttpClient的所有痛点。有了 HttpClientFactory,我们不需要关心如何创建HttpClient,又如何释放它。通过它可以创建具有特定业务的HttpClient,而且可以很友好的和 DI 容器结合使用,更为灵活。
HttpClientFactory 创建的HttpClient,也即是HttpClientHandler,只是这些个HttpClient被放到了“池子”中,工厂每次在create的时候会自动判断是新建还是复用。(默认生命周期为2min,默认的生命周期可以修改)
服务配置
新建一个类 用作service配置
/// <summary>/// 初始化HttpClient配置/// </summary>/// <param name="services"></param>public static void AddHttpClientSevice(this IServiceCollection services){if (services == null) throw new ArgumentNullException(nameof(services));//添加默认服务 没有指定服务名称的都可以使用默认服务services.AddHttpClient();//可以添加多个//获取自定义配置 每一个需要连接的对象都已使用指定名称的服务,所以服务需要命名var clientconfig = AppsettingConfig.HttpClientConfig;//我在appseeting中配置了是一个数组if (clientconfig?.Count > 0){foreach (var item in clientconfig){if (string.IsNullOrWhiteSpace(item.ServiceName)) continue;//检测服务名称services.AddHttpClient(item.ServiceName, client =>{client.BaseAddress = new Uri(item.BaseAddress);if (item.Timeout > 0)client.Timeout = TimeSpan.FromSeconds(item.Timeout);//设置超时if (item.DeafaultRequestHeader?.Count > 0)//添加默认headerforeach (var header in item.DeafaultRequestHeader){client.DefaultRequestHeaders.Add(header.Key, header.Value);//可以设置都有的Header 不能添加“Content-Type”}}).ConfigurePrimaryHttpMessageHandler(() =>{//配置代理 如果配有代理if (!item.Proxy.IsActive) return new HttpClientHandler();var hander = new HttpClientHandler(){AllowAutoRedirect = false,UseDefaultCredentials = true,};hander.Proxy = new WebProxy(item.Proxy.Host, item.Proxy.Port);//代理地址hander.Proxy.Credentials = new NetworkCredential(item.Proxy.UserName, item.Proxy.PassWord, item.Proxy.Domain);//账号。密码。域return hander;});}}}//注册封装类services.AddSingleton<IHttpHelper, HttpHelper>();}
StartUp中添加服务
//注册http请求服务 services.AddHttpClientSevice();封装HttpHelper
接口声明
public interface IHttpHelper { /// <summary> /// Get请求 /// </summary> /// <param name="url">完整的Url</param> /// <param name="headers">自定义header</param> /// <param name="servicename">服务名称</param> /// <returns></returns> public Task<HttpResponseMessage> GetAsync(string url, Dictionary<string, string> headers = null, string servicename = ""); /// <summary> /// Post请求 /// </summary> /// <param name="url">完整的Url</param> /// <param name="body">body体</param> /// <param name="headers">头</param> /// <param name="servicename">servicename</param> /// <returns></returns> public Task<HttpResponseMessage> PostAsync(string url, string body = "", Dictionary<string, string> headers = null, string servicename = ""); }接口实现
public class HttpHelper : IHttpHelper { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogHelper _logHelper; public HttpHelper(IHttpClientFactory httpClientFactory, ILogHelper logHelper) { _httpClientFactory = httpClientFactory; _logHelper = logHelper; } /// <summary> /// Get请求 /// </summary> /// <param name="url">完整的Url</param> /// <param name="headers">自定义header</param> /// <param name="servicename">服务名称</param> /// <returns></returns> public Task<HttpResponseMessage> GetAsync(string url, Dictionary<string, string> headers = null, string servicename = "") { try { HttpClient client; if (string.IsNullOrWhiteSpace(servicename)) { client = _httpClientFactory.CreateClient(); } else { client = _httpClientFactory.CreateClient(servicename); } if (headers?.Count > 0) { foreach (var item in headers) { client.DefaultRequestHeaders.Add(item.Key, item.Value); } } return client.GetAsync(url); } catch (Exception ex) { _logHelper.LogErr("HttpHelper.GetAsync", ex); throw ex; } } /// <summary> /// Post请求 /// </summary> /// <param name="url">完整的Url</param> /// <param name="body">body体</param> /// <param name="headers">头</param> /// <param name="servicename">servicename</param> /// <returns></returns> public Task<HttpResponseMessage> PostAsync(string url, string body = "", Dictionary<string, string> headers = null, string servicename = "") { try { HttpClient client; if (string.IsNullOrWhiteSpace(servicename)) { client = _httpClientFactory.CreateClient(); } else { client = _httpClientFactory.CreateClient(servicename); } if (headers?.Count > 0) { foreach (var item in headers) { client.DefaultRequestHeaders.Add(item.Key, item.Value); } } var content = new StringContent(body, Encoding.UTF8, "application/json"); return client.PostAsync(url, content); } catch (Exception ex) { _logHelper.LogErr("HttpHelper.PostAsync", ex); throw ex; } } }最后直接用就好 可以对返回的HttpResponseMessage进行操作,比如判断StatusCode 读取返回值 Content.ReadAsStringAsync()
