HTTP/3 是 HTTP 的第三个和最近标准化的主要版本。 HTTP/3 使用与 HTTP/1.1 和 HTTP/2 相同的语义:相同的请求方法、状态代码和消息字段适用于所有版本。 差异在于基础传输。 HTTP/1.1 和 HTTP/2 都将 TCP 用作其传输协议。 HTTP/3 使用与 HTTP/3 一起开发的传输技术,称为 QUIC。
与 HTTP/1.1 和 HTTP/2 相比,HTTP/3 和 QUIC 都有几种优势:
- 加快第一个请求的响应时间。 QUIC 和 HTTP/3 在客户端和服务器之间的往返次数较少时协商连接。 第一个请求会更快地到达服务器。
- 改进了连接数据包丢失时的体验。 HTTP/2 通过一个 TCP 连接多路复用多个请求。 如果在连接时发生数据包丢失,会影响所有请求。 这个问题称为“队头阻塞”。 由于 QUIC 提供本机多路复用,因此丢失的数据包只会影响已丢失数据的请求。
- 支持在网络之间转换。 此功能对于移动设备非常有用,在移动设备更改位置时,在 WIFI 和手机网络之间切换很常见。 目前,HTTP/1.1 和 HTTP/2 连接在切换网络时失败,并出现错误。 应用或 Web 浏览器必须重试任何失败的 HTTP 请求。 HTTP/3 让应用或 Web 浏览器在网络发生更改时可以无缝地继续。 HttpClient 和 Kestrel 不支持 .NET 7 中的网络转换。 它可能在未来版本中可用。
重要
配置为利用 HTTP/3 的应用应设计为也支持 HTTP/1.1 和 HTTP/2。 如果在 HTTP/3 中发现了问题,建议禁用 HTTP/3,直到在 .NET 的未来版本中解决问题为止。
HttpClient 设置
可以通过设置为 HttpRequestMessage.Version
3.0 来配置 HTTP 版本。 但是,由于并非所有路由器、防火墙和代理都正确支持 HTTP/3,因此建议将 HTTP/3 与 HTTP/1.1 和 HTTP/2 一起配置。 在 HttpClient
中,可以通过指定以下内容来完成操作。
- HttpRequestMessage.Version 到 1.1。
- HttpRequestMessage.VersionPolicy 至 HttpVersionPolicy.RequestVersionOrHigher。
平台依赖项
HTTP/3 使用 QUIC 作为其传输协议。 HTTP/3 的 .NET 实现使用 MsQuic 提供 QUIC 功能。 因此,对 HTTP/3 的 .NET 支持取决于 MsQuic 平台要求。 有关如何安装 MsQuic 的详细信息,请参阅 QUIC 平台依赖项。 如果运行 HttpClient 的平台没有 HTTP/3 的所有要求,则它将被禁用。
使用 HttpClient
下面的代码示例使用 顶级语句 ,并演示如何在请求中指定 HTTP3:
// See https://aka.ms/new-console-template for more information
using System.Net;
using var client = new HttpClient
{
DefaultRequestVersion = HttpVersion.Version30,
DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact
};
Console.WriteLine("--- localhost:5001 ---");
HttpResponseMessage resp = await client.GetAsync("https://localhost:5001/");
string body = await resp.Content.ReadAsStringAsync();
Console.WriteLine(
$"status: {resp.StatusCode}, version: {resp.Version}, " +
$"body: {body.Substring(0, Math.Min(100, body.Length))}");
.NET 6 中的 HTTP/3 支持
在 .NET 6 中,HTTP/3 作为 预览功能 提供,因为 HTTP/3 规范尚未完成。 .NET 6 的 HTTP/3 中可能存在行为或性能问题。 有关预览功能的详细信息,请参阅 预览功能规范。
若要在 .NET 6 中启用 HTTP/3 支持,请在项目文件中包括节点 RuntimeHostConfigurationOption
,以便启用 HTTP/3,其中包含 HttpClient
:
<ItemGroup>
<RuntimeHostConfigurationOption Value="true"
Include="System.Net.SocketsHttpHandler.Http3Support" />
</ItemGroup>
或者,可以从应用代码调用 System.AppContext.SetSwitch ,或将 DOTNET_SYSTEM_NET_HTTP_SOCKETSHTTPHANDLER_HTTP3SUPPORT
环境变量设置为 true
。 有关详细信息,请参阅 .NET 环境变量:DOTNET_SYSTEM_NET_HTTP_*。
要求 HTTP/3 配置标志的原因是在使用版本策略 RequestVersionOrHigher
时保护应用免受将来的破坏。 当调用当前使用 HTTP/1.1 和 HTTP/2 的服务器时,如果服务器后来升级到 HTTP/3,客户端将尝试使用 HTTP/3,并且可能不兼容,因为标准不是最终的,因此在发布 .NET 6 后可能会更改。
.NET 6 仅与 1.9.x 版本的 libmsquic 兼容。 由于库中的重大更改,Libmsquic 2.x 与 .NET 6 不兼容。 如果需要,Libmsquic 会接收对 1.9.x 的更新,以合并安全修补程序。
HTTP/3 服务器
在 .NET 6(预览版)和 .NET 7(全面支持)中,ASP.NET 通过 Kestrel 服务器支持 HTTP/3。 有关详细信息,请参阅 将 HTTP/3 与 ASP.NET Core Kestrel Web 服务器配合使用。
公共测试服务器
Cloudflare 托管了一个 HTTP/3 网站,可以在https://cloudflare-quic.com测试客户端。