如何让 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?的主要内容,如果未能解决你的问题,请参考以下文章

作为一个简单的 Unity 独立开发者,Mono 和 .NET 仍然让我感到困惑。谁是谁 ?谁做了啥?

如何让Markdown图片居中

android中如何让文字环绕图片

在H5中如何设置才能让安卓状态栏显示颜色?

在JSP中如何让页面一行显示20字

如何在JAVA中让一个线程死亡或结束