HTTP/3 es la tercera versión del protocolo de transferencia de Hipertexto para intercambio de información disponible desde el 2021. Http3 es compatible con la mayoría de los navegadores y servidores actuales. Esta versión nos entrega beneficios de rendimiento y soporte para usuarios de dispositivos móviles y conexiones más confiables.
Por ahora la idea es reemplazar el protocolo http por uno nuevo llamado QUIC que inicialmente fue desarrollado por Google eliminando algunos problemas de TCP para HTTP y obteniendo las siguientes ventajas:
- Configuración de conexiones más veloces mediante la combinación de los protocolos HTTP y TLS.
- Mejor manejo en la lógica de recuperación de pérdida de paquetes reduciendo bloqueos.
- Cuando saltamos de una red a otra no necesitamos reconectar a la red lo hará automáticamente.
Desde .Net 6 tenemos soporte HTTP/3 en los clientes HTTP, en GRPC y server Kestrel. Ambos implementan MSQuic, estas es la implementación de QUIC de la mano de Microsoft. Por el lado de los sistemas operativos Windows 11 y Windows Server 2022 soportan la nueva actualización. En el caso de linux necesitaremos instalar mixquic usando la libre libmsquic.
Primero crearemos un proyecto WebApi desde el Visual Studio. Luego necesitaremos agregar el soporte en el archivo csproj. esto puede hacerlo haciendo botón derecho sobre el proyecto y selecciones “Editar archivo de proyecto”.
Agregaremos la siguiente línea luego del <ImplicitUsings />.
<EnablePreviewFeatures>true</EnablePreviewFeatures>
El siguiente paso es configurar el host de Kestrel para que escuche los protocolos HTTP/1, HTTP/2 y HTTP/3. Dejaremos el soporte para las versiones anteriores por si algún cliente que nos consuma no lo soporta aun. Como es necesario conexión segura, no debemos olvidar de agregar el UseHttps. Nuestro progam.cs quedara algo asi.
using Microsoft.AspNetCore.Server.Kestrel.Core; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.WebHost.ConfigureKestrel((context, options) => { options.ListenAnyIP(5001, listenOptions => { listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3; listenOptions.UseHttps(); }); });
Hay una limitante para este proyecto, la mayoría de los navegadores no permite utilizar HTTP/3 para el localhost. Pero podemos ver el soporte en el encabezado de http, encontraremos en el header alt-svc con el valor h3.
Si deseamos verificar el soporte en la consola de ejecución de Kestrel debemos ir a nuestro archivo de configuración appsettings.json y agregar la siguiente línea.
"Microsoft.AspNetCore.Hosting.Diagnostics": "Information"
Veremos en la salida de la consola el soporte:
}
Por otro lado, es posible usar el registro de W3C y comprobar la versión de protocolo que usa el cliente. Debemos agregar las siguientes líneas en el program.cs.
builder.Services.AddW3CLogging(logging => { logging.LoggingFields = W3CLoggingFields.All; logging.LogDirectory = @"C:\logs"; logging.FlushInterval = TimeSpan.FromSeconds(2); }); ... app.UseW3CLogging();
Hasta ahora todo era para poder atender peticiones HTTP/3. Es el momento de configurar a nuestro cliente para que consuma. Primero debemos editar nuevamente el csproj para darle soporte y agregar las siguientes líneas:
<ItemGroup> <RuntimeHostConfigurationOption Include="System.Net.SocketsHttpHandler.Http3Support" Value="true" /> </ItemGroup>
Luego para consumir nuestro servicio anteriormente creado con nuestro cliente podemos hacerlo de la siguiente manera:
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/");
Esto es para todas las peticiones de nuestros clientes, pero es posible hacerlo para una petición específica con el siguiente código:
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();
Conclusiones
Este nuevo protocolo es el futuro y cada dia hay una gran cantidad de nuevos servicios soportándolo. Por esta razón, es un buen momento para comenzar a utilizarlo y probarlo para estar preparados para lo que se viene. Espero que les haya gustado y les sea útil.