dotnet团队官方博客发布了一篇HTTP3的文章:HTTP/3 support in .NET 6:https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/。文章介绍了.NET 6 将预览支持HTTP3,.NET 7正式支持HTTP3,原因主要是HTTP/3 的 RFC 尚未最终确定,因此仍然可以更改,并且在 .NET 6 中,HTTP/3 可能存在行为或性能问题。将 HTTP/3 包含在 .NET 6 中,可以开始尝试它。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 在客户端和服务器之间以较少的往返次数协商连接。 第一个请求更快地到达服务器,QUIC 使用 UDP 并内置 TLS,因此,当 TLS 握手作为连接的一部分发生时,建立连接会更快。

改进了发生连接数据包丢失时的体验。 HTTP/2 通过一个 TCP 连接多路复用多个请求。 如果在连接时发生数据包丢失,会影响所有请求。 这个问题称为“队头阻塞”。 由于 QUIC 提供本机多路复用,因此丢失的数据包只会影响已丢失数据的请求,因此在数据包丢失的情况下,它不再具有队头阻塞。支持在网络之间转换。 此功能对于移动设备非常有用,因为在移动设备更改位置时,在 WIFI 和移动电话网络之间切换是很常见的。 目前,在切换网络时,HTTP/1.1 和 HTTP/2 连接会失败并提示错误。 应用或 Web 浏览器必须重试任何失败的 HTTP 请求。 HTTP/3 让应用或 Web 浏览器在网络发生更改时可以无缝地继续。不过 Kestrel 并不支持 .NET 6 中的网络转换。 它可能在未来版本中可用。.NET的QUIC 支持QUIC被设计为 HTTP/3 的基础传输层,但它也可用于其他协议。它设计为适用于具有处理网络更改能力的移动设备,并在发生数据包丢失时具有良好的恢复能力。 在. NET 6 中并没有公开.NET QUIC API,目标是在.NET 7 中公开它们。QUIC 可以像 TCP Socket 一样使用,并不是特定于 HTTP/3,因此我们预计随着时间的推移,其他协议将建立在 QUIC 上,例如QUIC 上的 SMB。.NET 6 的 HTTP/3 支持HTTP/3 支持处于预览版状态,因此默认情况下没有启用。由于并非所有路由器、防火墙和代理都能正确地支持 HTTP/3,建议将 HTTP/3 与 HTTP/1.1 和 HTTP/2 一起配置。 可通过将 HttpProtocols.Http1AndHttp2AndHttp3 指定为终结点支持的协议来完成此操作。HTTP/3 将 QUIC 用作其传输协议。 HTTP/3 的 .NET 实现使用 MsQuic 来提供 QUIC 功能。 MSQuic 包含在 Windows 的特定版本中,并作为 Linux 的一个库。 如果 Kestrel 所运行的平台没有满足 HTTP/3 的所有要求,则它会被禁用。例如,HttpProtocols.Http1AndHttp2AndHttp3 允许 Kestrel 在支持 HTTP/3 的环境中启用 HTTP/3,并对 HTTP/1.1 和 HTTP/2 进行回退。WindowsWindows 11 内部版本 22000 或更高版本和Server 2022 RTM。

TLS 1.3 或更高版本的连接。上述 Windows 11 内部版本可能需要使用 Windows 预览体验成员内部版本Linux在 Linux 上,libmsquic 是通过 Microsoft 官方 Linux 包存储库 packages.microsoft.com 发布的。 为了使用它,必须手动添加。 请参阅 Microsoft 产品的 Linux 软件存储库。 添加 libmsquic 后,可以通过发行版的包管理器安装它,例如,对于 Ubuntu:sudo apt install libmsquicmacOSHTTP/3 目前在 macOS 上不受支持,主要是因为缺少与 QUIC 兼容的 TLS API。它可能在未来版本中可用。Alt-svcHTTP/3 是通过 alt-svc 标头作为从 HTTP/1.1 或 HTTP/2 的升级发现的。 这意味着,在切换到 HTTP/3 之前,第一个请求通常使用 HTTP/1.1 或 HTTP/2。 如果启用了 HTTP/3,则 Kestrel 会自动添加 alt-svc 标头。入门HTTP/3 是在应用启动时配置的。 下面的代码:将 WebHost 配置为 UseQuic。

配置端口 5001 以使用 HttpProtocols.Http1AndHttp2AndHttp3。首先要启用预览版特性,添加下列项目属性

True

public static async Task Main(string[] args)

{

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.ConfigureKestrel((context, options) =>

{

options.Listen(IPAddress.Any, 5001, listenOptions =>

{

// Use HTTP/3

listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;

listenOptions.UseHttps();

});

});

}HTTP/3 ClientHttpClient 已更新,以包括对 HTTP/3 的支持,但它需要启用运行时标记。在项目文件中包括以下内容,以便 HTTP/3 与 HttpClient 配合使用:

使用 HttpClient 进行 HTTP/3 请求时,需要额外的配置:将 HttpClient .DefaultRequestVersion 设置为 3.0,或者

将 HttpClient .DefaultVersionPolicy 设置为 HttpVersionPolicy.RequestVersionExact。// See https://aka.ms/new-console-template for more information

using System.Net;

var client = new HttpClient();

client.DefaultRequestVersion = HttpVersion.Version30;

client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact;

var resp = await client.GetAsync("https://localhost:5001/");

var body = await resp.Content.ReadAsStringAsync();

Console.WriteLine($"status: {resp.StatusCode}, version: {resp.Version}, body: {body.Substring(0, Math.Min(100, body.Length))}");gRpc over HTTP3gRPC 通常使用 HTTP/2 作为传输工具。HTTP/3 使用相同的语义,因此几乎不需要任何更改就能使其工作。由 .NET 团队提出 HTTP/3 的 gRPC 尚未成为标准:https://github.com/grpc/proposal/pull/256。.NET 团队将在.NET 7 中进一步开发 QUIC 和 HTTP/3,因此期待在预览过程中得到更新的功能。相关文章:https://devblogs.microsoft.com/dotnet/http-3-support-in-dotnet-6/https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/http3?view=aspnetcore-6.0

查看原文