翼度科技»论坛 编程开发 .net 查看内容

在.NET Core使用 HttpClient 的正确方式

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
前言
HttpClient 是 .NET Framework、.NET Core 或 .NET 5以上版本中的一个类,用于向 Web API 发送 HTTP 请求并接收响应。它提供了一些简单易用的方法,如 GET、POST、PUT 和 DELETE,可以很容易地构造和发送 HTTP 请求,并处理响应数据。它是我们比较常用的官方HTTP请求组件,那么你们都正确使用了吗?本文将探讨HttpClient的正确使用。
环境准备
首先我们用vs2022创建一个带默认 WeatherForcast 模板的 Web API 应用程序,以及一个普通的API的程序,项目使用的是.NET6。
项目结构如下

两个项目的功能点:
HttpClientTest - 返回天气预报的Web API
HttpClientTest2 -这个项目将用HttpClient来请求HttpClientTest 的天气预备。
接下来我们用4种方法来说明HttpClient的正确使用方法。
方法1
我们首先在HttpClientTest2 创建HttpClientTestController类,并写一个请求天气预备的方法,代码如下:
  1. namespace HttpClientTest2.Controllers
  2. {
  3.     [Route("api/[controller]")]
  4.     [ApiController]
  5.     public class HttpClientTestController : ControllerBase
  6.     {
  7.         [HttpGet]
  8.         public async Task<string> TestHttpClient()
  9.         {
  10.             var url = "https://localhost:7281/WeatherForecast";
  11.             #region 版本1
  12.             var httpClient = new HttpClient();
  13.             var response = await httpClient.GetAsync(url);
  14.             return await response.Content.ReadAsStringAsync();
  15.             #endregion
  16.           }
  17.        }
  18.    }    
复制代码
代码写完后,我们设置多项目启动,让这两个项目同时启动。

项目启动后,执行项目HttpClientTest2 的TestHttpClient请求接口。多执行几次。主要看看HttpClient后台的执行情况。这里可以用netstat来检查http的请求情况。
打开一个CMD控制台程序。输入如下代码:
  1. netstat -na | find "7281"
复制代码
7281端口是我们请求站点HttpClientTest。多次点击的效果如下:

由上面可以看出有多个请求,说明请求未关闭。接下来换第二种方法。
方法2
使用using命令来实现请求结束关闭请求,代码如下:
  1.    #region 版本2
  2.     using (var httpClient = new HttpClient())
  3.    {
  4.         var response = await httpClient.GetAsync(url);
  5.         return await response.Content.ReadAsStringAsync();
  6.    }
  7.    #endregion
  8.    //欢迎公众号:DOTNET开发跳槽
复制代码
同样我们多次请求,结果如下:

在这里可以看到状态“TIME_WAIT”,说明链接已经关闭,但实际情况链接还是占用着端口,在资源耗尽才会释放。这就是套连接的问题,套接字耗尽是指服务器上的可用套接字资源已经全部被占用,无法为新的连接提供服务。在 TCP/IP 网络通信中,每个端口上最多只能建立一个连接,这就限制了服务器可以处理的连接数。当服务器负载过高时,就可能导致套接字资源紧张,进而引发套接字耗尽问题。针对上面问题,继续对HttpClient 改进。
方法3
这里我们使用单例模式试一试。代码如下:
  1. public class HttpClientTestController : ControllerBase
  2.     {
  3.         private static HttpClient _httpClient;
  4.         static HttpClientTestController()
  5.         {
  6.             _httpClient = new HttpClient();
  7.         }
  8.         //注意:有许多方法可以实现单例模式。在这里使用了静态实例方法。
  9.         [HttpGet]
  10.         public async Task<string> TestHttpClient()
  11.         {
  12.             var url = "https://localhost:7281/WeatherForecast";
  13.             #region 版本3
  14.             //var response = await _httpClient.GetAsync(url);
  15.             //return await response.Content.ReadAsStringAsync();
  16.             #endregion
  17.         }
  18.     }
复制代码
代码编写完成后我们再试一试,结果如下:

因为使用了单例模式,没有创建新实例使用了相同的连接。这种方法解决了套接字耗尽问题。但是,我们注意到有一个状态为“已建立”的开放连接。如果有DNS更改或与网络相关的更改可能会影响连接,应用程序可能会失败,需要重新启动应用程序才能解决。这个方法也不是最理想的。
方法4
HttpClient是.NET内置方法,这里可以通过使用 IHttpClientFactory 接口来实现,从而避免上面的问题。代码如下:
  1. public class HttpClientTestController : ControllerBase
  2.     {
  3.         private readonly IHttpClientFactory _httpClientFactory;
  4.         public HttpClientTestController(IHttpClientFactory httpClientFactory)
  5.         {
  6.             _httpClientFactory = httpClientFactory;
  7.         }
  8.         [HttpGet]
  9.         public async Task<string> TestHttpClient()
  10.         {
  11.             var url = "https://localhost:7281/WeatherForecast";
  12.             #region 版本4
  13.             var httpClient = _httpClientFactory.CreateClient();
  14.             var response = await httpClient.GetAsync(url);
  15.             return await response.Content.ReadAsStringAsync();
  16.             #endregion
  17.         }
  18. //欢迎公众号:DOTNET开发跳槽
复制代码
使用IHttpClientFactory 的话,需要在Program.cs 中注入,代码如下:
  1. builder.Services.AddHttpClient();
复制代码
同样多次请求,然后执行netstat命令。效果如下:

从请求的状态来看,通过使用 _httpClientFactory.CreateClient() 完美解决问题。
结语
本文用四种方法渐进讲述了HttpClient的使用方法以及在使用过程中的问题,最终用IHttpClientFactory解决了出现的问题。希望本文对你有所收获,欢迎留言或者吐槽。
源码地址:https://github.com/xbhp/webapitest
参考:微软官方文档
  1. 来源公众号:DotNet开发跳槽
复制代码
来源:https://www.cnblogs.com/xbhp/archive/2023/04/12/17309933.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具