添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一、为什么不用 HttpClient

  1. HttPClient 使用完之后不会立即关闭开启网络连接时会占用底层 socket 资源,但在 HttpClient 调用其本身的 Dispose 方法时,并不能立刻释放该资源

  2. 如果频繁的使用 HttpClient ,频繁的打开链接,关闭链接消耗就会很大。

二、解决方案

  1. 我们可以延长 HttpClient 的生命周期,比如对其建一个静态的对象
private static HttpClient Client = new HttpClient();
  1. 或者使用单例模式,至于你使用哪一种单例模式就看你自己了,这里就不细将了。因为这样感觉起来不是很舒服

三、HttpClientFactory

  1. .NET Core 2.1版本之后引入的 HttpClientFactory解决了HttpClient的所有痛点。有了 HttpClientFactory,我们不需要关心如何创建HttpClient,又如何释放它。通过它可以创建具有特定业务的HttpClient,而且可以很友好的和 DI 容器结合使用,更为灵活。

  2. HttpClientFactory 创建的HttpClient,也即是HttpClientHandler,只是这些个HttpClient被放到了“池子”中,工厂每次在create的时候会自动判断是新建还是复用。(默认生命周期为2min,默认的生命周期可以修改)

//修改默认的生命周期
services.AddHttpClient().SetHandlerLifetime(TimeSpan.FromMinutes(5));

四、HttpClientFactory的使用

一、第一种使用方式

  1. Startup.cs中进行注册
//注册http请求服务
services.AddHttpClient();
  1. Httphelper请求辅助类中使用
/// <summary>
/// 注入http请求
/// </summary>
private readonly IHttpClientFactory httpClientFactory;
public HttpHelp(IHttpClientFactory _httpClientFactory)
        httpClientFactory = _httpClientFactory;
    // <summary>
    // Get请求数据
    // <para>最终以url参数的方式提交</para>
    // </summary>
    // <param name="parameters">参数字典,可为空</param>
    // <param name="requestUri">例如/api/Files/UploadFile</param>
    // <returns></returns>
public async Task < string > Get(Dictionary < string, string > parameters, string requestUri, string token)
    //从工厂获取请求对象
    var client = httpClientFactory.CreateClient();
    //添加请求头
    if(!string.IsNullOrWhiteSpace(token))
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
    client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
    //拼接地址
    if(parameters != null)
        var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value));
        requestUri = string.Concat(requestUri, '?', strParam);
    client.BaseAddress = new Uri(requestUri);
    return client.GetStringAsync(requestUri).Result;
  1. 然后我们在Startup.cs对相对的类进行注册就可以了使用了。

二、使用命名客户端

  1. Startup.cs中进行注册,这个注册可以存在多个。以创建名字区分
services.AddHttpClient("github", c =>
    c.BaseAddress = new Uri("https://xxxxxxx.com/");
    // Github API versioning
    c.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
    // Github requires a user-agent
    c.DefaultRequestHeaders.Add("Authorization", "asfasfasdsgdsfsdfsdafasfas");
});
  1. 使用方式和上面的一样只要
/// <summary>
/// 注入http请求
/// </summary>
private readonly IHttpClientFactory httpClientFactory;
public HttpHelp(IHttpClientFactory _httpClientFactory)
        httpClientFactory = _httpClientFactory;
    // <summary>
    // Get请求数据
    // <para>最终以url参数的方式提交</para>
    // </summary>
    // <param name="parameters">参数字典,可为空</param>
    // <param name="requestUri">例如/api/Files/UploadFile</param>
    // <returns></returns>
public async Task < string > Get(Dictionary < string, string > parameters, string requestUri, string token)
    //从工厂获取请求对象   声明自己创建哪一个httpClient客户端
    var client = httpClientFactory.CreateClient("github");
    //添加请求头
    if(!string.IsNullOrWhiteSpace(token))
        client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
    client.DefaultRequestHeaders.Add("Content-Type", "application/json; charset=utf-8");
    //拼接地址
    if(parameters != null)
        var strParam = string.Join("&", parameters.Select(o => o.Key + "=" + o.Value));
        requestUri = string.Concat(requestUri, '?', strParam);
    client.BaseAddress = new Uri(requestUri);
    return client.GetStringAsync(requestUri).Result;

三、类型化客户端

  1. 创建一个类
public class HttpClienService
    public HttpClient Client { get; }
    public HttpClienService(HttpClient client)
        client.BaseAddress = new




    
 Uri("https://xxxx.com/");
        // GitHub API versioning
        client.DefaultRequestHeaders.Add("Authorization",
            "xxxxxxxxxxxx");
        // GitHub requires a user-agent
        client.DefaultRequestHeaders.Add("Content-Type",
            "application/json; charset=utf-8");
        Client = client;
    //这个下面就是编写自己方法,进行调用
  1. Startup.cs中进行注册,这个注册可以存在多个。
services.AddHttpClient<classHttp>();
//注册之后,使用依赖注入的方式进行注入,进行使用。

IHttpClientFactory

利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期。

当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用WebAPI的方法以检查终结点是否正常工作。要实现这一点,通常需要实例化HttpClient并使用该实例来调用你的方法。但是直接使用HttpClient也有一些缺点,主要与手动管理实例的生命周期有关。

你可以使用IHttpClientFactory创建HttpClient来避免这些问题。IHttpClientFactory是在.Net Core 2.1引入的,它提供了一个命名,配置和创建HttpClient实例的核心功能,并能自动管理实例的池化和生命周期。

为什么使用IHttpClientFactory

尽管HttpClient没有直接实现IDisposable接口,但它扩展了System.Net.HttpHttpMessageInvoker,这个类实现了IDisposable。然而,当使用HttpClient实例时,你不应该手动操作释放它们。尽管可以在HttpClient实例上调用Dispose方法,但不推荐这样做。
应该怎么做呢?一种选择是使HttpClient静态化,或者将HttpClient的非静态实例包装在自定义类中,并使其成为单例类。但是更好的替代方法是使用IHttpClientFactory来生成HttpClient的实例,然后使用该实例来调用操作方法。

当你释放HttpClient实例时,连接将保持打开状态长达4分钟。此外,可以在任何时间点打开socket的数量是有限制的——不能同时打开太多socket。因此,当使用太多HttpClient实例时,可能会耗尽socket
这就是IHttpClientFactory的意义所在。你可以通过利用IHttpClientFactory来创建用于调用HTTP API方法的HttpClient实例,以避免HttpClient所面临的问题。在ASP.NET Core中实现IHttpClientFactory的主要目标是为了确保使用工厂模式创建HttpClient实例的同时避免socket耗尽。

IHttpClientFactoryHttpClientFactory

IHttpClientFactory是一个由DefaultHttpClientFactory类实现的接口,这是一个工厂模式。DefaultHttpClientFactory实现了IHttpClientFactoryIHttpMessageHandlerFactory接口。IHttpClientFactory提供了ASP.NET Core对创建、缓存和处理HttpClient实例提供了出色的内置支持。
请注意,HttpClientFactory只是一个帮助类,用于创建使用提供的处理程序配置的HttpClient实例。这个类有以下方法:?

Create(DelegatingHandler[])
Create(HttpMessageHandler,DelegatingHandler[])
CreatePipeline(HttpMessageHandler,IEnumerable<DelegatingHandler>)

重载的HttpClientFactory类的Create方法看起来像这样:?

public static HttpClient Create(params DelegatingHandler[] handlers)
 return Create(new HttpClientHandler(), handlers);
public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
 HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers);
 return new HttpClient(pipeline);

引入HttpClientFactoryIHttpClientFactory是为了更好地管理HttpMessageHandler实例的生命周期。

在ASP.NET Core中注册IHttpClientFactory实例

你可以在Startup类的ConfigureServices方法中,通过调用IServiceCollection实例上的AddHttpClient扩展方法注册一个IHttpClientFactory类型的实例,如下:?

public void ConfigureServices(IServiceCollection services)
  services.AddControllersWithViews();
  services.AddHttpClient();

IHttpClientFactory实例注入到控制器

可以通过如下代码将将IHttpClientFactory实例注入到控制器:?

public class HomeController : Controller
   private IHttpClientFactory _httpClientFactory;
   private readonly ILogger<HomeController> _logger;
   public HomeController(ILogger<HomeController> logger,
   IHttpClientFactory httpClientFactory)
      _logger = logger;
      _httpClientFactory = httpClientFactory;

Action中调用HttpClient

要通过使用IHttpClientFactory创建HttpClient,应该调用CreateClient方法。一旦HttpClient实例可用,就可以在HomeController类的index方法中使用以下代码来调用ValuesController类的Get方法。

public async Task<IActionResult> Index()
  HttpClient httpClient = _httpClientFactory.CreateClient();
  httpClient.BaseAddress = new Uri("http://localhost:5000/");
  var response = await httpClient.GetAsync("/api/values");
  string str = await response.Content.ReadAsStringAsync();
  List<string> data = JsonSerializer.Deserialize<List<string>>(str);
  return View(data);

使用IHttpClientFactory在ASP.NET Core中创建和管理HttpClient实例

有几种方法可以在应用程序中使用IHttpClientFactory。这包括直接使用IHttpClientFactory、使用命名client和类型client
基本的或一般的使用模式,即直接使用IHttpClientFactory。请参考“注册一个IHttpClientFactory实例”一节,该节讨论了如何注册HttpClient实例。

如果你想使用不同配置的HttpClient实例,以下是一个不错的选择。下面的代码片段说明了如何创建。

services.AddHttpClient("github", c =>
  c.BaseAddress = new Uri("https://api.github.com/");
  c.DefaultRequestHeaders.Add("Accept",
  "application/vnd.github.v3+json");
  c.DefaultRequestHeaders.Add("User-Agent", "This is a test user agent");
});

第二种方法是使用包装了HttpClient实例的自定义类,该自定义类封装了通过HTTP协议调用所有终结点的逻辑。下面的代码片段说明了如何定义自定义HttpClient类。

public class ProductService : IProductService
  private IHttpClientFactory _httpClientFactory;
  private readonly HttpClient _httpClient;
  private readonly string _baseUrl = "http://localhost:1810/";
  public ProductService(HttpClient httpClient)
    _httpClient = httpClient;
  public async Task<Catalog> GetAllProducts()
    _httpClient = _httpClientFactory.CreateClient();
    _httpClient.BaseAddress = new Uri(_baseUrl);
    var uri = "/api/products";
    var result = await _httpClient.GetStringAsync(uri);
    return JsonConvert.DeserializeObject<Product>(result);

通过以下代码注册自定义的client

services.AddHttpClient<IProductService, ProductService>();

MessageHandler添加到命名管道中

MessageHandler是扩展自HttpMessageHandler类,它可以接受HTTP请求并返回HTTP响应。如果你想构建自己的MessageHandler,你应该创建一个继承DelegatingHandler的类。

你可以将HttpMessageHandler添加到请求处理管道中。可以在Startup类的ConfigureServices方法中使用以下代码将HttpMessageHandler添加到管道中。

public void ConfigureServices(IServiceCollection services)
  services.AddHttpClient("github", c =>
    c.BaseAddress = new Uri("https://api.github.com/");
  .AddHttpMessageHandler<DemoHandler>();
  services.AddTransient<DemoHandler>();

IHttpClientFactory是一个自.net Core 2.1以来就可用的工厂类。如果你使用IHttpClientFactory来创建HttpClient实例,那么底层HttpClientMessagehandler实例的池化和生命周期将自动管理。IHttpClientFactory还负责处理一些常见问题,比如日志记录。

控制台中使用HttpClientFactory

整体说明:这里主要是借助依赖注入程序,在控制台上获取需要的相关类,然后进行使用对应方法的调用

(1).首先需要添加依赖注入的程序集【Microsoft.Extensions.DependencyInjection

(2).添加所需组件对应的程序集,并进行Addxxxx

(3).创建Provicder

(4).利用Provider调用GetService获取对应对象

  1. HttpClientFactory
    添加程序集:【Microsoft.Extensions.Http
var serviceCollection = new ServiceCollection(); serviceCollection.AddHttpClient(); var serviceProvider = serviceCollection.BuildServiceProvider(); //var serviceProvider = new ServiceCollection().AddHttpClient().BuildServiceProvider(); //等价于以上三句话 IHttpClientFactory httpClientFactory = serviceProvider.GetService < IHttpClientFactory > (); //下面是使用 string url2 = "http://XXX:8055/Home/SendAllMsg"; var client = httpClientFactory.CreateClient(); var content = new StringContent("msg=123", Encoding.UTF8, "application/x-www-form-urlencoded"); var response = client.PostAsync(url2, content).Result; string result = ""; if(response.IsSuccessStatusCode) result = response.Content.ReadAsStringAsync().Result; 实例的自定义类,该自定义类封装了通过HTTP协议调用所有终结点的逻辑。整体说明:这里主要是借助依赖注入程序,在控制台上获取需要的相关类,然后进行使用对应方法的调用。的非静态实例包装在自定义类中,并使其成为单例类。是在.Net Core 2.1引入的,它提供了一个命名,配置和创建。实例,以下是一个不错的选择。,而且可以很友好的和 DI 容器结合使用,更为灵活。实例的核心功能,并能自动管理实例的池化和生命周期。也有一些缺点,主要与手动管理实例的生命周期有关。只是一个帮助类,用于创建使用提供的处理程序配置的。
此文是在官方文档的基础上做的个人笔记,一些简单的内容就没用再列出来了,参考官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/http-requests?view=aspnetcore-5.0 IHttpClientFactory有以下几个优势: 便于与Polly、Refit等第三方库继承。 将委托添加到http请求管道中,实现类似asp.net core中间件的功能。 因为复用HttpClientMessageHandler可.
详解netcore 使用get post调用接口方法实例 首先编辑Startup.cs文件,找到ConfigureServices方法,并将HttpClient中间件添加进来 services.AddHttpClient() 在要使用HttpClient的 Service或cootrller中,进行将HttpClient的注入 private readonly IHttpClientFactory HttpClientFactory; public BaseCoreServi
一、为什么不用HttpClient 1.HttPClient使用完之后不会立即关闭开启网络连接时会占用底层socket资源,但在HttpClient调用其本身的Dispose方法时,并不能立刻释放该资源
.net core使用HttpClient请求api,有很多资源的问题,比如使用using的时候,虽然可以释放资源,但是套接字(socket)也不会立即释放,所以.net core2.1中,新增了IHttpClientFactory.将其用于配置和创建应用中的HttpClient实例。这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑HttpClient实例。...
IHttpClientFactory 是由自 .NET Core 2.1 起可用的固定工厂 DefaultHttpClientFactory 实现的协定,用于创建在应用程序中使用HttpClient 实例。 .NET 中提供的原始 HttpClient 类的相关问题 常见的原始 HttpClient 类非常易于使用,但在某些情况下,许多开发人员却并未正确使用该类。 虽然此类实现 IDisposable,但在 using 语句中声明和实例化它并非首选操作,因为释放 HttpClient 对象时,基础套接字
之所以称ASP.NET Core是一个Web开发平台,源于它具有一个极具扩展性的请求处理管道,我们可以通过这个管道的定制来满足各种场景下的HTTP处理需求。ASP. NET Core应用的很多特性,比如路由、认证、会话、缓存等,也同时定制消息处理管道来实现的。我们甚至可以通过管道定制在ASP.NET Core平台上创建我们自己的Web框架,实际上MVC和SingalR这两个重要的Web框架也是采用这样的方式创建的。 HTTP协议自身的特性决定了任何一个Web应用的工作方式都是监听、接收并处理HTTP请求,并在最终对请求予以响应,HTTP请求处理是管道式设计典型的应用场景。我们根据H
导读:本文已添加在 晨曦微服务之旅 ,现在自己在尝试微服务架构,一边学边做项目快速的进入状态。当然在学习的过程中会将自己学到的知识进行分享。 一、为什么不用HttpClient         1.HttPClient使用完之后不会立即关闭开启网络连接时会占用底层socket资源,但在HttpClient调用其本身的Dispose方法时,并不能立刻释放该资源 2.如果频繁的使用HttpClient,频繁的打开链接,关闭链接消耗就会很大。 二、解决方案         1.我们可以延长HttpClient的生命周期,比如对其建一个静态的对象 private static HttpClient
利用IHttpClientFactory可以无缝创建HttpClient实例,避免手动管理它们的生命周期。 当使用ASP.Net Core开发应用程序时,可能经常需要通过HttpClient调用WebAPI的方法以检查终结点是否正常工作。要实现这一点,通常需要实例化HttpClient使用该实例来调用你的方法。但是直接使用HttpClient也有一些缺点,主要与手动管理实例的生命周期有关。 你可以使用IHttpClientFactory创建HttpClient来避免这些问题。IHttpClientFa
public static string GetUserIP(IHttpContextAccessor httpContextAccessor) var Request = httpContextAccessor.HttpContext.Request; string realIP = null; string forwa. import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig
.NET Core 中发起 HTTP POST 请求可以使用内置的 HttpClient 类。 以下是一个使用 HttpClient 发起 POST 请求的示例: using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; namespace HttpClientExample class Program static async Task Main(string[] args) var client = new HttpClient(); var content = new StringContent("{\"key\":\"value\"}", Encoding.UTF8, "application/json"); var response = await client.PostAsync("https://www.example.com/api/values", content); var responseString = await response.Content.ReadAsStringAsync(); Console.WriteLine(responseString); Console.ReadKey(); 在上面的代码中,我们创建了一个 HttpClient 实例,然后创建了一个名为 `content` 的 StringContent 实例,它代表了我们想要发送的数据。 最后,我们调用了 `PostAsync` 方法并将 `content` 作为参数。它会返回一个 `HttpResponseMessage` 实例,该实例包含了服务器的响应。 请注意,使用 HttpClient 时需要注意它的处理方式,以避免内存泄漏和性能问题。建议使用单例或依赖注入的方式管理 HttpClient