一. 背景

1.前世

  提到HttpClient,在传统的.Net版本中简直臭名昭著,因为我们安装官方用法 using(var httpClient = new HttpClient()),当然可以Dispose,但是在高并发的情况下,连接来不及释放,socket被耗尽,然后就会出现一个喜闻乐见的错误:即各种套接字的问题。

 Unable to connect to the remote serverSystem.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted.

PS:当然我们可以通过修改注册表的默认值,来人为的减少超时时间,但可能会引起其他莫名其妙的问题:

 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay])

2.我们之前的解决方案

  把HttpClient做成全局单例的,通过共享一个实例,减少了套接字的浪费,实际上由于套接字重用而传输快一点。

 关于单例的封装,详见这篇: https://www.cnblogs.com/yaopengfei/p/10301779.html

  封装成单例的也会有些不灵活的地方:

(1).因为是复用的 HttpClient,那么一些公共的设置就没办法灵活的调整了,如请求头的自定义。

(2).因为 HttpClient 请求每个 url 时,会缓存该url对应的主机 ip,从而会导致 DNS 更新失效(TTL 失效了)。

3.HttpClientFactiory应运而生

  HttpClientFactory 是 ASP.NET CORE 2.1 中新增加的功能。顾名思义 HttpClientFactory 就是 HttpClient 的工厂,内部已经帮我们处理好了对 HttpClient 的管理,不需要我们人工进行对象释放,同时,支持自定义请求头,支持 DNS 更新。

分析:

  HttpClient 继承自 HttpMessageInvoker,而 HttpMessageInvoker 实质就是HttpClientHandler。HttpClientFactory 创建的 HttpClient,也即是 HttpClientHandler,只是这些个 HttpClient 被放到了“池子”中,工厂每次在 create 的时候会自动判断是新建还是复用。(默认生命周期为 2min)。简单的理解成 Task 和 Thread 的关系。

4. 补充请求方式的说明

  其中Post请求有两种,分别是: "application/x-www-form-urlencoded"表单提交的方式 和 "application/json" Json格式提交的方式。

(1). Post的表单提交的格式为:"userName=admin&pwd=123456"。

(2). Post的Json的提交格式为:将实体(类)转换成json字符串。

 

二. 几种用法

用到的服务器端的方法:

    /// <summary>
    /// 充当服务端接口
    /// </summary>
    public class ServerController : Controller
    {
        [HttpGet]
        public string CheckLogin(string userName, string pwd)
        {
            if (userName == "admin" && pwd == "123456")
            {
                return "ok";
            }
            else
            {
                return "error";
            }
        }

        [HttpPost]
        public string Register1(string userName, string pwd)
        {
            if (userName == "admin" && pwd == "123456")
            {
                return "ok";
            }
            else
            {
                return "error";
            }
        }

        [HttpPost]
        public string Register2([FromBody]UserInfor model)
        {
            if (model.userName == "admin" && model.pwd == "123456")
            {
                return "ok";
            }
            else
            {
                return "error";
            }
        }

    }
View Code

相关文章:

  • 2021-06-23
  • 2021-05-27
  • 2021-10-18
  • 2022-12-23
  • 2021-11-21
  • 2021-12-26
  • 2021-12-04
  • 2021-11-25
猜你喜欢
  • 2021-11-04
  • 2021-12-28
  • 2021-11-18
  • 2021-12-29
  • 2021-08-04
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案