介紹
之前我給大家講過使用GitHub Actions 做CI/CD,今天看到一篇不錯的文章拿來翻譯下
源作者鏈接:https://www.meziantou.net/using-http-3-quic-in-dotnet.htm
正文
什么是 HTTP/3
HTTP/3 是 HTTP 的新版本。大多數現代瀏覽器和服務器都支持 HTTP/3 協議。此更新應主要為移動用戶或不可靠的連接帶來性能優勢。主要思想是用一個新的協議QUIC來代替TCP,它消除了TCP for HTTP的一些問題。因此,QUIC 具有以下優點(並非詳盡列表):
- 通過結合 TCP 和 TLS 握手更快地建立連接
- 通過更好地處理丟包恢復邏輯來減少線頭阻塞
- 連接遷移,因此您在網絡之間移動時無需重新連接(握手)(例如 WIFI 到蜂窩)
如果您想詳細了解什么是 HTTP/3,可以閱讀以下文章:
- https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/
- https://www.smashingmagazine.com/2021/08/http3-performance-improvements-part2/
- https://www.smashingmagazine.com/2021/09/http3-practical-deployment-options-part3/
- https://blog.cloudflare.com/http-3-vs-http-2/
- https://techcommunity.microsoft.com/t5/networking-blog/deploying-http-3-on-windows-server-at-scale/ba-p/2839394?WT.mc_id=DT-MVP-5003978
- https://eng.snap.com/quic-at-snap/
.NET 6 支持客戶端(HttpClient包括 gRPC)和服務器(Kestrel)的 HTTP/3。此實現基於MsQuic,是IETF QUIC協議的 Microsoft 實現。請注意,在 .NET 6 中仍處於預覽狀態,因此您需要在 csproj 或代碼中顯式啟用它。目前,.NET 支持 HTTP/3:
- Windows 11 和 Windows Server 2022
- Linux(您可能需要msquic使用安裝apt install libmsquic)
- 雖然msquic支持使用 OpenSSL 的 macOS,但 .NET 實現目前不支持它。事實上,.NET 團隊更喜歡依賴操作系統安全 API,而不是添加新的依賴項,SecureTransport比如 macOS。這避免了集成問題,例如證書管理。但是,SecureTransport不公開實現 QUIC 的方法。
服務端(Kestrel)
您首先需要在 csproj 中啟用預覽功能:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>
</Project>
然后,您可以將 Kestrel 配置為偵聽 HTTP/1、HTTP/2 和 HTTP/3。支持舊協議很重要,因為並非所有客戶端都支持新協議。此外,HTTP/3 需要安全連接,因此您必須使用UseHttps.
using Microsoft.AspNetCore.Server.Kestrel.Core;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, options) =>
{
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
listenOptions.UseHttps();
});
});
var app = builder.Build();
app.MapGet("/", () => "hello world");
app.Run();
大多數瀏覽器不允許localhost地址使用 HTTP/3。但是,您可以通過查看響應標頭來驗證它是否有效。響應應包含具有值的alt-svc標頭h3:
您還可以通過啟用更詳細的日志記錄來檢查服務器使用 HTTP/3。appsettings.json您可以在或中更改配置appsettings.Development.json:
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "Information"
}
}
}
然后,您應該在日志中看到以下內容:
您還可以使用 W3C 日志記錄並檢查客戶端使用的協議版本:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddW3CLogging(logging =>
{
logging.LoggingFields = W3CLoggingFields.All;
logging.LogDirectory = @"C:\logs";
logging.FlushInterval = TimeSpan.FromSeconds(2);
});
builder.WebHost.ConfigureKestrel((context, options) =>
{
...
});
var app = builder.Build();
app.UseW3CLogging();
app.MapGet("/", () => "hello world");
app.Run();
客戶端 (HttpClient)
有兩種方法可以啟用 HTTP/3 支持HttpClient:
- 編輯 csproj 以添加運行時選項
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Net.SocketsHttpHandler.Http3Support"
Value="true" />
</ItemGroup>
</Project>
- 在創建第一個之前設置以下開關 HttpClient
System.AppContext.SetSwitch("System.Net.SocketsHttpHandler.Http3Support", true);
然后,您可以使用HttpClient向 HTTP/3 服務器發出請求:
using var client = new HttpClient();
client.DefaultRequestVersion = HttpVersion.Version30;
// The client falls back to HTTP2 or HTTP1 if HTTP3 is not supported
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
// Will use HTTP3 if the server supports it
var data = await client.GetStringAsync("https://localhost:5001/");
您還可以為特定請求啟用 HTTP3:
using var request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:5001/");
request.Version = HttpVersion.Version30;
request.VersionPolicy = HttpVersionPolicy.RequestVersionExact;
using var response = await client.SendAsync(request);
var data = await response.Content.ReadAsStringAsync();
結語
聯系作者:加群:867095512 @MrChuJiu