introduce
I told you about using GitHub Actions to do CI/CD before. Today I saw a good article to translate
Source Author link: https://www.meziantou.net/using-http-3-quic-in-dotnet.htm
text
What is HTTP/3
HTTP/3 is a new version of HTTP. Most modern browsers and servers support HTTP/3 protocol. This update should primarily bring performance benefits to mobile users or unreliable connections. The main idea is to replace TCP with a new protocol QUIC, which eliminates some problems of TCP for HTTP. Therefore, QUIC has the following advantages (not an exhaustive list):
- Establish connections faster by combining TCP and TLS handshakes
- Reduce thread head blocking by better handling packet loss recovery logic
- Connection migration, so you don't need to reconnect (shake hands) when moving between networks (e.g. WIFI to cell)
If you want to know more about HTTP/3, you can read the following articles:
- 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 supports HTTP/3 for clients (HttpClient including gRPC) and servers (Kestrel). This implementation is based on MsQuic and is a Microsoft implementation of IETF QUIC protocol. Please note that in NET 6 is still in the preview state, so you need to explicitly enable it in csproj or code. At present NET supports HTTP/3:
- Windows 11 and Windows Server 2022
- Linux (you may need apt install lib msquic)
- msquic supports Mac OS using OpenSSL, but NET implementation does not support it at present. In fact NET team prefers to rely on the operating system security API rather than adding new dependencies, such as SecureTransport and macOS. This avoids integration issues, such as certificate management. However, SecureTransport does not disclose the method of implementing QUIC.
Server (Kestrel)
You first need to enable the preview function in csproj:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net6.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <EnablePreviewFeatures>true</EnablePreviewFeatures> </PropertyGroup> </Project>
You can then configure Kestrel to listen to HTTP/1, HTTP/2, and HTTP/3. Supporting the old protocol is important because not all clients support the new protocol. In addition, HTTP/3 requires a secure connection, so you must use 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();
Most browsers do not allow HTTP/3 for localhost addresses. However, you can verify that the response header is valid by looking at it. The response should contain an alt SVC header with a value h3:
You can also check that the server uses HTTP/3 by enabling more detailed logging. appsettings.json you can change the configuration Appsettings in or Development. json:
{ "DetailedErrors": true, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "Microsoft.AspNetCore.Hosting.Diagnostics": "Information" } } }
Then you should see the following in the log:
You can also use W3C logging to record and check the protocol version used by the client:
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();
Client (HttpClient)
There are two ways to enable HTTP/3 support for HttpClient:
- Edit csproj to add runtime options
<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>
- Set the following switch HttpClient before creating the first one
System.AppContext.SetSwitch("System.Net.SocketsHttpHandler.Http3Support", true);
You can then use HttpClient to make a request to the HTTP/3 server:
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/");
You can also enable HTTP3 for specific requests:
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();
epilogue
Contact author: Jia Qun: 867095512 @ mrchujiu