如何让 GrpcChannel 在 MonoAndroid 上使用 HTTP/2?
Posted
技术标签:
【中文标题】如何让 GrpcChannel 在 MonoAndroid 上使用 HTTP/2?【英文标题】:How to make GrpcChannel use HTTP/2 on MonoAndroid? 【发布时间】:2021-12-28 06:27:54 【问题描述】:我正在尝试通过MagicOnion 协议向我的服务器发出请求(它使用来自 gRPC 的传输,但不使用序列化协议,message pack 而不是 protobuf)。
一个简单的测试客户端应用程序,在net5.0
下工作,正在执行如下代码:
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var address = $"http://ServerUrl.Host:5002";
using var channel = GrpcChannel.ForAddress(address);
var myServiceClient = MagicOnionClient.Create<IMyService>(channel);
var result = await myServiceClient.GetMyData();
...并成功收到响应。但是,如果我尝试在 android 应用程序上执行相同的代码,我会在服务器日志中看到此异常消息:
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2ConnectionErrorException: HTTP/2 connection error (PROTOCOL_ERROR): Invalid HTTP/2 connection preface.
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ParsePreface(ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.TryReadPrefaceAsync()
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Connection.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
通过日志和流量转储,我可以看到 .Net 5 上的客户端使用 HTTP/2
,但在 Android 上 - HTTP/1.1
。如我所见,这是请求之间的唯一区别。
那么,我怎样才能让Android(API30,monoandroid10.0)客户端使用HTTP/2
?
【问题讨论】:
【参考方案1】:解决方法是使用另一个 gRPCC 实现库 - Grpc.Core。它提供了与 MagicOnion 兼容的 GrpcChannel
类。
在我的情况下,该库没有立即工作,抛出关于 libgrpc_csharp_ext
加载问题的错误。要解决这个问题,您还必须添加 pacakge Grpc.Core.Xamarin。
用法示例:
var channel = new Grpc.Core.Channel(ServerUrl.Host, 5002, Grpc.Core.ChannelCredentials.Insecure);
var myServiceClient = MagicOnionClient.Create<IMyService>(channel);
var result = await myServiceClient.GetMyData();
【讨论】:
以上是关于如何让 GrpcChannel 在 MonoAndroid 上使用 HTTP/2?的主要内容,如果未能解决你的问题,请参考以下文章