You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
7.6 KiB
Plaintext

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"# HttpClient 概述"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 作用\n",
"HttpClient是一个用于发送HTTP请求和接收HTTP响应的类。它提供了一种现代化、灵活和强大的方式来与Web服务进行通信。HttpClient类位于System.Net.Http命名空间下可以通过NuGet包管理器进行安装。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## 整体理解"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![图](./Assets/概要图.svg) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"HttpClient是应用程序进程中封装调用远程请求的类库。整个远程的执行是由进程向操作系统申请经由网卡、路由器等网络设备转换、传输到一台Web服务器然后返回的过程, HttpClient只是其中一个很小的环节。\n",
"\n",
"在这个基础上理解初代HttpClient问题(网络套接字用完 DNS问题等)、使用原则、请求管道、工厂模式、类型化客户端、Polly等项时会很轻松。比如即便使用Using包括了 HttpClient也会有套接字耗尽的问题是因为using只能释放进程中的对象但进程管理不了系统及网卡(这是在进程之上的),更不用说路由和互联网及被调用方的服务器了。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 前世今生"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### WebRequest\n",
"这是.NET创建者最初开发用于使用HTTP请求的标准类。\n",
"\n",
"使用HttpWebRequest可以让开发者控制请求/响应流程的各个方面,如 timeouts, cookies, headers, protocols。另一个好处是HttpWebRequest类不会阻塞UI线程。例如当您从响应很慢的API服务器下载大文件时您的应用程序的UI不会停止响应。\n",
"\n",
"HttpWebRequest通常和WebResponse一起使用一个发送请求一个获取数据。HttpWebRquest更为底层一些能够对整个访问过程有个直观的认识但同时也更加复杂一些。\n",
"\n",
"### WebClient\n",
"WebClient是一种更高级别的抽象是HttpWebRequest为了简化最常见任务而创建的使用过程中你会发现他缺少基本的headertimeoust的设置不过这些可以通过继承httpwebrequest来实现。使用WebClient可能比HttpWebRequest直接使用更慢大约几毫秒。但这种“低效率”带来了巨大的好处它需要更少的代码和隐藏了细节处理更容易使用并且在使用它时你不太可能犯错误。\n",
"\n",
"### HttpClient\n",
"HttpClient提供强大的功能并提供了异步支持可以轻松配合async await 实现异步请求等。\n",
"\n",
"随着更新发展,已经解决了前期问题(套接字耗尽、DNS、不灵活等),并发展了完整、完善的体系(基于Task的异步、连接池、类型化的客户端、工厂模式、Polly等)。\n",
"\n",
"是本项目的学习目标。"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## HttpClient架构图\n",
"\n",
"### .NetFramework 4及4.5 架构\n",
"HttpClient最初是作为NuGet包提供的该包可以选择包含在.NET Framework 4.0项目中。在.NET Framework 4.5中它作为BCL基本类库的一部分在框中提供。它建立在预先存在的HttpWebRequest实现之上。在.NET Framework中ServicePoint API可用于控制和管理HTTP连接包括通过为端点配置ConnectionLeaseTimeout来设置连接寿命。\n",
"\n",
"![.NetFramework](./Assets/架构.001.png)\n",
"\n",
"### .NET Core 1.0及1.1 架构\n",
".NET Core 1.0最初于2016年6月发布。与.NET Framework中可用的版本相比此第一个版本的API接口要小得多主要用于构建ASP.NET Core Web应用程序。由于.NET Core 1.0是HttpClient因此提供了API。但是不包括用于HttpWebRequest和ServicePoint的API。.NET Core 1.0中的HttpClient直接建立在使用非托管代码的OS平台API之上Windows API使用WinHTTPLinux和Mac使用LibCurl。\n",
"\n",
"值得注意的是到2016年8月很快就注意到重新使用HttpClient实例以防止套接字耗尽的建议有一个相当麻烦的副作用DNS\n",
"\n",
"![.NetFramework](./Assets/架构.002.png)\n",
"\n",
"### .NET Core 2.0 架构\n",
"在.NET Core 2.0中添加了HttpWebRequest以支持.NET Standard 2.0。它位于HttpClient实现的顶层这与.NET Framework 4.5+中的工作原理相反。还添加了ServicePoint尽管它的许多API接口要么要么会抛出未实现的异常要么根本就没有实现。\n",
"\n",
"![.NetFramework](./Assets/架构.003.png)\n",
"\n",
"### .NET CORE 2.1及后续 架构\n",
"这种有问题的行为导致团队不同团队进行了两项工作。\n",
"\n",
"ASP.NET团队开始研究**Microsoft.Extensions.Http包该包的主要功能是IHttpClientFactory**。这个针对HttpClient实例自用的工厂还包括基础HttpMessageHandler链的生命周期管理。如果您想了解有关此功能的更多信息可以查看我的系列博客文章我将在此介绍。\n",
"\n",
"IHttpClientFactory功能是作为ASP.NET Core 2.1的一部分发布的,对于许多人来说,这是一个很好的折衷方案,它解决了连接重用以及生命周期管理的问题。\n",
"\n",
"在同一时间范围内,.NET团队正在研究自己的解决方案。该团队也在.NET Core 2.1中发布在HttpClient的处理程序链的核心引入了一个新的**SocketsHttpHandler**。该处理程序直接建立在Socket API之上并在托管代码中实现HTTP。这项工作的一部分包括连接池系统以及为这些连接设置最大生存期的能力。\n",
"\n",
"![.NetFramework](./Assets/架构.004.png)\n",
"\n",
"说明:虽然默认情况下从.NET Core 2.1启用了SocketsHttpHandler但实现仅限于HTTP / 1.1通信。那些需要HTTP / 2的用户必须禁用该功能并使用较旧的处理程序链该处理程序链像以前一样依赖非托管代码并且不包括连接池。\n",
"\n",
"幸运的是,.NET Core 3.0中已消除了此限制并且现在提供了HTTP/2支持。这应该使用基于适合所有对象的SocketsHttpHandler链的HttpClient。\n",
"\n",
"结语:从.Net core 2.1开始,架构逐步稳定、完善。.Net 5、6、7、8中逐渐发展出一整套完整机制包括但不限于 连接池、工厂模式、Polly等。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 后续\n",
"\n",
"后续将从基础使用到高级使用,一步步展开,一步步学习。"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}