在.NET 8的C#中配置gRPC客户端用HTTP/3:客户端始终用HTTP/2
gRPC客户端无法使用HTTP/3通信问题
服务器配置(已验证支持HTTP/3)
public static class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // 配置Kestrel启用HTTP/3 builder.WebHost.ConfigureKestrel(options => { options.ListenAnyIP(7227, listenOptions => { // listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3; listenOptions.Protocols = HttpProtocols.Http3; listenOptions.UseHttps(@"X:\YYYYY\ZZZ\localhost.pfx", "SomePassword"); // HTTP/3必须使用HTTPS }); }); // 配置日志 builder.Logging.ClearProviders(); builder.Logging.AddConsole(); // 注册服务 builder.Services.AddGrpc(); var app = builder.Build(); // 配置请求管道 app.MapGrpcService<GreeterService>(); app.MapGet("/", () => "gRPC端点必须通过gRPC客户端访问。如需创建客户端,请查看官方文档。"); app.Use(async (context, next) => { var protocol = context.Request.Protocol; Console.WriteLine($"使用的协议: {protocol}"); await next.Invoke(); }); app.Run(); } }
客户端配置(期望使用HTTP/3通信)
internal static class Program { private static async Task Main(string[] args) { // 配置日志 var loggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); builder.SetMinimumLevel(LogLevel.Trace); }); // 配置HttpClientHandler支持HTTP/3 var httpHandler = new SocketsHttpHandler { SslOptions = new SslClientAuthenticationOptions { EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls13 }, EnableMultipleHttp2Connections = true, AutomaticDecompression = DecompressionMethods.All, MaxConnectionsPerServer = 10 }; httpHandler.SslOptions.ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http3 }; // 测试环境跳过证书验证(生产环境禁止使用) httpHandler.SslOptions.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; // 创建HttpClient var httpClient = new HttpClient(httpHandler) { // 设置服务器地址 BaseAddress = new Uri("https://localhost:7227") }; // 创建gRPC通道 var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions { HttpClient = httpClient, LoggerFactory = loggerFactory, }); var client = new Greeter.GreeterClient(channel); // 调用SayHello方法 var reply = await client.SayHelloAsync(new HelloRequest { Name = "World" }); Console.WriteLine("响应: " + reply.Message); // 关闭通道 await channel.ShutdownAsync(); Console.WriteLine("按任意键退出..."); Console.ReadKey(); } }
使用的NuGet包
客户端包
<PackageReference Include="Grpc.Net.Client" Version="2.64.0" /> <PackageReference Include="Grpc.Tools" Version="2.65.0" PrivateAssets="All" /> <PackageReference Include="Google.Protobuf" Version="3.27.2" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" /> <PackageReference Include="System.Net.Http" Version="4.3.4" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
服务器包
<PackageReference Include="Grpc.AspNetCore" Version="2.64.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
问题
无论如何调整客户端配置,始终使用HTTP/2与服务器通信,无法启用HTTP/3。
解决方案
升级并清理依赖包
- 移除客户端的
Microsoft.AspNetCore.Server.Kestrel包:客户端无需引用Kestrel,且2.2.0版本完全不支持HTTP/3(HTTP/3在.NET 6+才正式支持)。 - 移除客户端的
System.Net.Http包:.NET Core 3.1及以后版本已内置该组件,旧版本包会引发版本冲突。 - 确保客户端与服务器的
Grpc相关包版本保持一致,且项目基于.NET 6或更高版本开发。
- 移除客户端的
启用HTTP/3支持配置
在客户端的SocketsHttpHandler配置中添加HTTP/3启用开关:var httpHandler = new SocketsHttpHandler { // 原有配置... EnableHttp3 = true // 显式启用HTTP/3支持 };确保运行环境支持QUIC
HTTP/3基于QUIC协议,需满足:- 服务器和客户端均运行在.NET 6+环境;
- 操作系统支持QUIC:Windows 11/Server 2022及以上、Linux内核5.6+、macOS 11+。
调试调整服务器监听配置(可选)
暂时将服务器的监听协议改为同时支持HTTP/2和HTTP/3,方便排查兼容性问题:listenOptions.Protocols = HttpProtocols.Http1AndHttp2AndHttp3;
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

