首页 > 其他分享 >在.NET Core使用 HttpClient 的正确方式

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

时间:2023-04-12 15:35:26浏览次数:57  
标签:Core 请求 await var NET HttpClient response httpClient

前言

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类,并写一个请求天气预备的方法,代码如下:

namespace HttpClientTest2.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HttpClientTestController : ControllerBase
    {
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本1
            var httpClient = new HttpClient();
            var response = await httpClient.GetAsync(url);
            return await response.Content.ReadAsStringAsync();
            #endregion
          }
       }
   }    

代码写完后,我们设置多项目启动,让这两个项目同时启动。

图片

项目启动后,执行项目HttpClientTest2 的TestHttpClient请求接口。多执行几次。主要看看HttpClient后台的执行情况。这里可以用netstat来检查http的请求情况。

打开一个CMD控制台程序。输入如下代码:

netstat -na | find "7281"

7281端口是我们请求站点HttpClientTest。多次点击的效果如下:

图片

由上面可以看出有多个请求,说明请求未关闭。接下来换第二种方法。

方法2

使用using命令来实现请求结束关闭请求,代码如下:

   #region 版本2
    using (var httpClient = new HttpClient())
   {
        var response = await httpClient.GetAsync(url);
        return await response.Content.ReadAsStringAsync();
   }
   #endregion
   //欢迎公众号:DOTNET开发跳槽

同样我们多次请求,结果如下:

图片

在这里可以看到状态“TIME_WAIT”,说明链接已经关闭,但实际情况链接还是占用着端口,在资源耗尽才会释放。这就是套连接的问题,套接字耗尽是指服务器上的可用套接字资源已经全部被占用,无法为新的连接提供服务。在 TCP/IP 网络通信中,每个端口上最多只能建立一个连接,这就限制了服务器可以处理的连接数。当服务器负载过高时,就可能导致套接字资源紧张,进而引发套接字耗尽问题。针对上面问题,继续对HttpClient 改进。

方法3

这里我们使用单例模式试一试。代码如下:

public class HttpClientTestController : ControllerBase
    {
        private static HttpClient _httpClient;
        static HttpClientTestController()
        {
            _httpClient = new HttpClient();
        }
        //注意:有许多方法可以实现单例模式。在这里使用了静态实例方法。
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本3
            //var response = await _httpClient.GetAsync(url);
            //return await response.Content.ReadAsStringAsync();
            #endregion
        }
    }

代码编写完成后我们再试一试,结果如下:

图片

因为使用了单例模式,没有创建新实例使用了相同的连接。这种方法解决了套接字耗尽问题。但是,我们注意到有一个状态为“已建立”的开放连接。如果有DNS更改或与网络相关的更改可能会影响连接,应用程序可能会失败,需要重新启动应用程序才能解决。这个方法也不是最理想的。

方法4

HttpClient是.NET内置方法,这里可以通过使用 IHttpClientFactory 接口来实现,从而避免上面的问题。代码如下:

public class HttpClientTestController : ControllerBase
    {
        private readonly IHttpClientFactory _httpClientFactory;
        public HttpClientTestController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本4
            var httpClient = _httpClientFactory.CreateClient();
            var response = await httpClient.GetAsync(url);
            return await response.Content.ReadAsStringAsync();
            #endregion
        }
//欢迎公众号:DOTNET开发跳槽

使用IHttpClientFactory 的话,需要在Program.cs 中注入,代码如下:

builder.Services.AddHttpClient();

同样多次请求,然后执行netstat命令。效果如下:

图片

从请求的状态来看,通过使用 _httpClientFactory.CreateClient() 完美解决问题。

结语

本文用四种方法渐进讲述了HttpClient的使用方法以及在使用过程中的问题,最终用IHttpClientFactory解决了出现的问题。希望本文对你有所收获,欢迎留言或者吐槽。

源码地址:https://github.com/xbhp/webapitest

参考:微软官方文档

来源公众号:DotNet开发跳槽

标签:Core,请求,await,var,NET,HttpClient,response,httpClient
From: https://www.cnblogs.com/xbhp/p/17309933.html

相关文章

  • C# .NET 压缩ZIP时 OOM OutOfMemoryException
    C#.NET压缩ZIP时OOM OutOfMemoryException.ZipArchiveEntry、ZipEntry、SharpZipLib、ZipOutputStream、OutOfMemoryException. 解决方法:可以把零散的文件,存到某个文件夹。再调用ZipFile.CreateFromDirectory来压缩。usingSystem.IO.Compression;Console.WriteLine(......
  • .NET 8新预览版本使用 Blazor 组件进行服务器端呈现
    简介此预览版添加了对使用Blazor组件进行服务器端呈现的初始支持。这是Blazor统一工作的开始,旨在使Blazor组件能够满足客户端和服务器端的所有WebUI需求。这是该功能的早期预览版,因此仍然受到一定限制,但我们的目标是无论选择如何构建应用,都能使用可重用的Blazor组件。......
  • Asp.NetWebApi跨域解决方案
    最近新开项目,项目初期本地部署访问webapi,api采用JWT验证,发现加上Authorization请求头后就报跨域问题,网上很多方案例如修改webconfig请求头什么的,均测试未果,多方尝试后有了以下方案,一行代码便完全解决跨域问题,特此记录!1、NuGet下载Microsoft.AspNet.WebApi.Cors  2、App_Sta......
  • testng+HttpClient项目实战(一)
    参考文档:https://www.cnblogs.com/yingyingja/p/9973960.htmlhttps://www.cnblogs.com/yingyingja/p/9974181.htmlhttps://www.cnblogs.com/yingyingja/p/9974183.htmlhttps://www.cnblogs.com/yingyingja/p/9974186.htmlhttps://www.cnblogs.com/yingyingja/p/9974189.html......
  • Netty与Spring Boot的整合实现(转)
    来源:https://www.jb51.net/article/168212.htm最近有朋友向我询问一些Netty与SpringBoot整合的相关问题,这里,我就总结了一下基本整合流程,也就是说,这篇文章,默认大家是对netty与Spring,SpringMVC的整合是没有什么问题的。现在,就进入正题吧。Server端:总的来说,服务端还是比较简单的,......
  • win10、win2016离线安装 .netframework3.5
    下载地址:(网上收集的)   https://pan.baidu.com/s/1O24nLgXhehHveae25p9SLg密码:amgu   https://url93.ctfile.com/f/29519493-531656763-281351(访问密码:8843)   https://soft.3dmgame.com/down/205311.html下载NetFx3.cab后将其放于C盘WINDOWS文件夹下(C:\Windows)点击“......
  • asp.net webform 允许跨域
    voidApplication_BeginRequest(objectsender,EventArgse){//允许跨域请求的域名列表,可以根据需求进行修改string[]allowedOrigins=newstring[]{"http://example1.com","http://example2.com"};//获取请求来源stringorigin=HttpContex......
  • Kubernetes客户端认证(二)—— 基于ServiceAccount的JWTToken认证
    1、概述在Kubernetes官方手册中给出了“用户”的概念,Kubernetes集群中存在的用户包括“普通用户”与“ServiceAccount”,但是Kubernetes没有普通用户的管理方式,通常只是将使用集群根证书签署的有效证书的用户都被视为合法用户。那么对于使得Kubernetes集群......
  • Ado.net与EF的区别?
    运行效率方面:Ado.net更好,直接通过Command、Connection等命令写sql语句进行CRUD操作。开发效率方面:EF开发起来更快,代码可读性好。只需操作对象,使用C#语法完成数据库操作。适用性方面:EF适合大型项目,数据量大。Ado.net适合小型项目,运行效率高。......
  • .NET 个人博客系统
    前言之前通过github学习了一个.netcore的博客项目,最近也是完成了博客的备案,完善了一下。该项目是传统的MVC项目,可以进行主题的切换,采用Bootstrap进行前台页面的展示,有配套的后台管理系统,可以解析Markdown文件。参观地址ZY知识库可以将个人的意见评论到该文章,我可以采纳采纳。......