.NET 4.7客户端对接.NET 6.0 gRPC服务遇HTTP/2兼容问题求助
现有一个基于.NET 6.0构建的解决方案,需要被另一个受限于.NET 4.7的项目调用其功能。采用gRPC实现跨框架通信时,.NET 4.7客户端出现通信错误。此前在Windows 10环境下,.NET 6.0服务端与同框架客户端通信正常,但切换为.NET 4.7客户端后无法建立连接。推测核心原因是.NET 4.7对HTTP/2的支持存在限制,而.NET 6.0默认使用HTTP/2进行gRPC通信,因此需要替代的绑定方案。
System.InvalidOperationException: 'The channel configuration isn't valid on this operating system. The channel is configured to use WinHttpHandler and the current version of Windows doesn't support HTTP/2 features required by gRPC. Windows Server 2022 or Windows 11 or later is required.'
string gRPCNetworkIP = "127.0.0.1"; int gRPCNetworkPort = 50051; //Creating gRPC service and Starting gRPC Network Console.WriteLine("Creating gRPC service and Starting gRPC Network..."); var server = gRPCNetworkCongig(samsungGalaxyA50Driver, gRPCNetworkIP, gRPCNetworkPort); Console.WriteLine("gRPC service and gRPC Network are created and started"); Console.ReadKey();
public static Server gRPCNetworkCongig(Driver driver, string gRPCIP, int gRPCPort) { Server server = new Server(); server.Ports.Add(new ServerPort(gRPCIP, gRPCPort, ServerCredentials.Insecure)); server.Services.Add(DriverService_gRPC.DriverService_gRPC.BindService(new DriverService(driver))); // Start the gRPC server server.Start(); return server; }
static async Task Main(string[] args) { string gRPCNetworkIP = "127.0.0.1"; int gRPCNetworkPort = 50051; string desiredDevice_1 = "CUO 4B2A"; string desiredDevice_2 = "BT-S2"; string desiredDevice_3 = "BLA"; string baseAddress = $"http://{gRPCNetworkIP}:{gRPCNetworkPort}"; var channel = GrpcChannel.ForAddress(baseAddress); var client = new DriverService_gRPC.DriverService_gRPC.DriverService_gRPCClient(channel); //await client.OpenSettingsAsync(new OpenSettingsRequest()); testcase_BT(client, desiredDevice_2); Console.ReadKey(); } public static async void testcase_BT(DriverService_gRPC.DriverService_gRPC.DriverService_gRPCClient driver, string desiredDevice) { Console.WriteLine("Opening Bluetooth Settings ..."); await driver.OpenBluetoothSettingsAsync(new OpenBluetoothSettingsRequest()); Console.WriteLine("Bluetooth Settings Openned"); Console.WriteLine($"Reading {desiredDevice} state ..."); var readStateResponse = await driver.ReadDeviceStateAsync(new ReadDeviceStateRequest { DesiredDevice = desiredDevice }); Console.WriteLine($"{desiredDevice} is {readStateResponse.State}"); Console.WriteLine("Testcase ended"); }
方案1:启用gRPC-Web兼容(推荐)
gRPC-Web允许gRPC通信在HTTP/1.1上运行,完美适配.NET 4.7客户端的限制,无需升级操作系统或框架版本。
服务端修改(.NET 6)
- 安装NuGet包
Grpc.AspNetCore.Web - 在服务启动配置中启用gRPC-Web支持:
// 假设使用.NET 6的最小API模型,在Program.cs中添加: builder.Services.AddGrpc(); builder.Services.AddGrpcWeb(); var app = builder.Build(); app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true }); app.MapGrpcService<DriverService>();
如果是传统的HostBuilder配置,对应调整中间件顺序即可。
客户端修改(.NET 4.7)
- 安装NuGet包
Grpc.Net.Client.Web - 修改通道初始化代码,使用
GrpcWebHandler包裹HTTP客户端:
string baseAddress = $"http://{gRPCNetworkIP}:{gRPCNetworkPort}"; // 创建支持gRPC-Web的HTTP客户端 var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWebText, new HttpClientHandler())); var channel = GrpcChannel.ForAddress(baseAddress, new GrpcChannelOptions { HttpClient = httpClient }); var client = new DriverService_gRPC.DriverService_gRPC.DriverService_gRPCClient(channel);
这样客户端就可以通过HTTP/1.1与.NET 6的gRPC服务通信,避开HTTP/2的限制。
方案2:改用WCF作为通信替代
如果gRPC的调整成本较高,可以考虑使用WCF实现跨框架通信:
- .NET 4.7原生支持WCF客户端,兼容性极佳
- .NET 6可以通过
System.ServiceModel.Http包搭建WCF服务端,或者使用WCF客户端调用现有服务 - 需要重新定义服务契约和数据契约,适配跨框架序列化需求
方案3:升级客户端框架(备选)
如果业务允许将客户端项目升级到.NET 5+,则可以直接使用原生gRPC客户端,无需额外配置即可与.NET 6服务端通信,但此方案受限于用户对.NET 4.7的依赖限制。
内容的提问来源于stack exchange,提问作者Seif Elkady

