在.Net Core应用开发中,调用第三方接口也是常有的事情,HttpClient使用人数、使用频率算是最高的一种了,在.Net Core中,HttpClient的使用方式随着版本的升级也发生了一些变化,本次就讲解一下Asp.Net Core2.1前后使用的两种方式。

一、原先HttpClient使用方式

  一般来讲,喜欢要用的时候才会选择去获取资源,因此,当在有需求时才会用HttpClient去调用资源,便会使用如下这种方式或其它方式获取资源。

//do something...
using (var httpClient = new HttpClient())
{
var requestUri = "http://aspnetcore.online/api/resource/getresource";
var httpResponseMessage = await httpClient.GetAsync(requestUri);
//do something... return Ok(httpResponseMessage);
}

  如果可以正常访问目标地址的话,则会返回相应的资源信息。  

  

  又如Post方式提交并返回相应的内容,都是可以直接使用。

//do something...
using (var httpClient = new HttpClient())
{
var requestUri = "http://aspnetcore.online/api/resource/postresource";
var httpResponseMessage = await httpClient.PostAsJsonAsync(requestUri,"星城软件");
//do something... return Ok(httpResponseMessage);
}

  但是这种情况下会出现一个严重的问题,在不停的调用情形下,tcp连接数会被耗尽,虽然使用using方式调用HttpClient并在退出前调用Dispose()方法将HttpClient释放了,但是tcp连接仍然处于保持状态,在240s后才会自动断开,这里就涉及到一个连接状态了,首先得理解下http的工作原理,http协议是建立在tcp协议基础之上,当浏览器需要从服务器获取数据的时候,会发出一次http请求。http会通过tcp建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,http会立即将tcp连接断开,这个过程是很短的。所以http连接是一种短连接,是一种无状态的连接。但是tcp的连接只要我们不通过代码把连接关闭,这个连接就会在客户端和服务端的进程中一直存在,相关状态数据会一直保存着,直到无响应状态持续了默认关闭时间后自动断开。

  

  当短期请求量过大时,这就可能导致了"套接字资源耗尽异常",因此,为了解决这个问题,想到不释放HttpClient,将它作为单例一直使用,实现单例方式有很多种。

  如使用单例模式,只生成一个HttpClient

private static HttpClient _httpClient = null;
public HttpClient CreateHttpClient()
{
if (_httpClient == null) _httpClient = new HttpClient();
return _httpClient;
}

  亦或是在初始化时完成单例注入,创建一个IHttpClient接口,及相应的实现StandardHttpClient,实现类种加入HttpClient属性,在实现类构造函数中完成初始化后便可直接使用该实现类完成资源请求工作。

//在startup中完成单例注入
services.AddSingleton<IHttpClient, StandardHttpClient>(); public interface IHttpClient
{
//do something
} public class StandardHttpClient : IHttpClient
{
private HttpClient _client; public StandardHttpClient()
{
_client = new HttpClient();
} //do something...
}

  虽然这样解决了"套接字资源耗尽异常",但是又带来了新的问题,熬不过DNS生存时间(TTL),当主机 DNS 更新时,又可能产生异常,提示无法解析主机名称,因为单例HttpClient不会随着主机DNS更新而更新,Singleton HttpClient doesn't respect DNS changes

An error occurred while sending the request. Couldn't resolve host name An error occurred while sending the request. Couldn't resolve host name

 

二、现有HttpClient使用方式

  在.Net Core2.1后,微软引入了HttpClientFactory彻底解决这个问题,工厂模式的职责是负责创建对象,这个类主要负责创建HttpClient实例

  首先在StartUp中注册,可能会提示安装这个Nuget包

 services.AddHttpClient();

  该方法内部实现过程可以浏览:https://www.cnblogs.com/lizhizhang/p/9502862.html

  其次,在需要使用时,使用构造函数注入即可

[Route("api/[controller]")]
[ApiController]
public class HttpClientController : ControllerBase
{
IHttpClientFactory _httpClientFactory; public HttpClientController(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
} [HttpGet]
[Route(nameof(Index))]
public async Task<IActionResult> Index()
{
var client = _httpClientFactory.CreateClient();
var result = await client.GetAsync("http://aspnetcore.online/api/resource/getresource");
return Ok(result);
}
}

  具体实现原理简述为:HttpClientFactory内部管理着一个连接句柄池,对每一个HttpClient使用一个句柄进行跟踪管理,当该实例使用完毕后,句柄仍然控制资源释放,在短期大量处理时,可以将这部分句柄完成对不同实例的跟踪管理,使得句柄,也就是相应的套接字生命周期延长,对套接字完成了复用。

 近日,长沙.NET技术社区已经建立,微信群:长沙.NET社区一群已满,如有需要来长沙发展或是回归长沙可以进入二群,加一下我来邀请进去。各大城市间的人才拉锯战进行中,不管是什么行业,什么职业,长沙都应留住人才,培养人才

 

2019-02-26,望技术有成后能回来看见自己的脚步

Asp.Net Core中HttpClient的使用方式的更多相关文章

  1. asp.net core 中灵活的配置方式

    asp.net core支持外部文件和命令行参数方式来配置系统运行所需要的配置信息,我们从下面两个常用场景来具体说下具体使用方法. 一.监听地址及端口配置 1,命令行方式 asp.net core系统 ...

  2. 在Asp.Net Core中使用DI的方式使用Hangfire构建后台执行脚本

    最近项目中需要用到后台Job,原有在Windows中我们会使用命令行程序结合计划任务或者直接生成Windows Service,现在.Net Core跨平台了,虽然Linux下也有计划任务,但跟原有方 ...

  3. 在ASP.NET Core中构建路由的5种方法

    原文链接 :https://stormpath.com/blog/routing-in-asp-net-core 在ASP.NET Core中构建路由的5种方法 原文链接 :https://storm ...

  4. C#调用接口注意要点 socket,模拟服务器、客户端通信 在ASP.NET Core中构建路由的5种方法

    C#调用接口注意要点   在用C#调用接口的时候,遇到需要通过调用登录接口才能调用其他的接口,因为在其他的接口需要在登录的状态下保存Cookie值才能有权限调用, 所以首先需要通过调用登录接口来保存c ...

  5. ASP.NET Core中Middleware的使用

    https://www.cnblogs.com/shenba/p/6361311.html   ASP.NET 5中Middleware的基本用法 在ASP.NET 5里面引入了OWIN的概念,大致意 ...

  6. ASP.NET Core教程:在ASP.NET Core中使用HttPClient调用WebService

    一.前言 在以前的一篇文章中,曾经讲述过如何在ASP.NET Core中调用WebService.但是那种方式是通过静态引用的方式去调用的,如果是在生产环境中,肯定不能使用这种方式去调用,幸运的是微软 ...

  7. 初探CSRF在ASP.NET Core中的处理方式

    前言 前几天,有个朋友问我关于AntiForgeryToken问题,由于对这一块的理解也并不深入,所以就去研究了一番,梳理了一下. 在梳理之前,还需要简单了解一下背景知识. AntiForgeryTo ...

  8. ASP.NET Core中如何针对一个使用HttpClient对象的类编写单元测试

    原文地址: How to unit test a class that consumes an HttpClient with IHttpClientFactory in ASP.NET Core? ...

  9. ASP.NET Core中如何调整HTTP请求大小的几种方式

    一.前言 一般的情况下,我们都无需调用HTTP请求的大小,只有在上传一些大文件,或者使用HTTP协议写入较大的值时(如调用WebService)才可能会调用HTTP最大请求值. 在ASP.NET Co ...

随机推荐

  1. Android之淘宝商品列表长按遮罩效果

    先来看看淘宝.唯品会长按商品的效果,以及简单Demo的效果:        首先分析一下场景: 长按条目时,弹出遮罩的效果遮挡在原来的条目布局上: 页面滑动或点击其他的条目,上一个正在遮罩的条目遮罩消 ...

  2. HTML DOM innerHTML 属性及实现图片连续播放

    定义和用法 innerHTML 属性设置或返回表格行的开始和结束标签之间的 HTML. 语法 tablerowObject.innerHTML=HTML 实例 下面的例子返回了表格行的 inner H ...

  3. .NET开发微信小程序-微信支付

    前台MD5加密代码 /* * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algor ...

  4. C Primer Plus 第9章 函数 编程练习

    复习题: 8. int choice(int a,int b,int c){ int max; max = a; if (b > max) max = b; if (c > max) ma ...

  5. .NET Core使用微软官方类库实现汉字转拼音

    一.NuGet包 拼音:Install-Package SimplifiedChinesePinYinConversion 简体-繁体互转:Install-Package TraditionalChi ...

  6. adSage :2013年教育行业搜索引擎投放分析报告

  7. golang项目中使用条件编译

    golang项目中使用条件编译 C语言中的条件编译 golang中没有类似C语言中条件编译的写法,比如在C代码中可以使用如下语法做一些条件编译,结合宏定义来使用可以实现诸如按需编译release和de ...

  8. Java开源生鲜电商平台-账单模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-账单模块的设计与架构(源码可下载) 补充说明:Java开源生鲜电商平台-账单模块的设计与架构,即用户的账单形成过程. 由于系统存在一个押账功能的需求,(何为押账,就是形成公司 ...

  9. TSL1401线性CCD TM32F103开发平台移植源代码

    Technorati Tags: stm32 模块资料 对于线性CCD而言,开发着更多的是基于飞思卡尔系列单片机进行开发,前几天在做项目的时候需要用到该传感器,故使用了蓝宙CCD的驱动历程,然后对蓝宙 ...

  10. 静态代码扫描工具PMD定制xml的规则(一)操作篇

    0.前言 PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工 ...