为什么 Xamarin Android 发送 GRPC/Http2 请求失败?

3
我正在尝试运行来自Dot net conf 2019 keynote的Xamarin Forms示例。我已经托管了grpc服务,.net core控制台应用程序可以无问题地从中获取数据。但是,在运行xamarin应用程序时,ALPN协商(客户端hello)使用http 1.1进行,因此grpc调用失败。源代码在此处可用 错误消息: Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Bad gRPC response. Response protocol downgraded to HTTP/1.1." 调试器显示,在xamarin下使用的SocketsHttpHandler没有支持Http 2的代码。 问题:
  1. 显然 Xamarin 支持 Grpc 和 Http,为什么会失败? 如果我的怀疑是正确的,那么问题是因为 xamarin 使用一个不支持 Http2 的旧版本 System.Net.Http.dll。
  2. 如何确保 Xamarin 使用支持 Http2 的正确运行时程序集?
  3. 如果对某人有效,请分享系统配置。

配置

使用共享运行时:true
Mono 共享运行时版本(在 Android 设备上看到的):10.1.0-18。
Windows 10 上的 Visual Studio 2019:
Xamarin.Android SDK 10.1.4.0(d16-4/e44d1ae)
Xamarin.Android 参考程序集和 MSBuild 支持。
Mono: fd9f379
Java.Interop: xamarin/java.interop/d16-4@c4e569f
Xamarin.Android 工具: xamarin/xamarin-android-tools/d16-5@9f4ed4b

我尝试过的事情:

  1. 从ModernHttpClient切换到Managed HttpClient实现/NativeMessageHandler。仍然出现相同的错误。(因为ALPN协商仍使用相同的代码?)
  2. 使用Version 2发送HttpRequestMessage到新的HttpClient。仍然使用相同的基础处理程序。所以无法协商Http2。
  3. 禁用共享运行时。没有起作用。

在.net core控制台应用程序中,由SocketsHttpHandler使用的HttpConnectionSettings具有支持http2的代码: HttpConnectionSettings used by the SocketsHttpHandler has http2 supporting code

但是在xamarin上没有。选择AndroidClientHandler,但是委托给SocketsHttpHandler。它的设置不具备http2支持: Xamarin fails


你在iOS上试过这个吗? - cost
@cost 我没有在iOS上尝试过,只在安卓上测试了。 - Kavinda Gayashan
2个回答

5
我已经使用您提供的解决方案使其可用。抱歉我没有详细说明您的方式为什么不起作用,而这个新方法却可以。同时,我无法测试iOs版本。 服务器。我只更改了端口版本,并使用了发布版。顺便说一下,我不确定您是否能够成功运行Http1AndHttp2和相同的ip和端口。我在个人项目中遇到了问题。 移动端。将Grpc.CoreGrpc.Core.Api nugets添加到两个项目中。
我正在以另一种方式创建通道。您提供的解决方案版本是:
var channel = GrpcChannel.ForAddress("123.123.123.123:123456");

我的版本已经改变为

var channel = new Channel("123.123.123.123:123456", ChannelCredentials.Insecure);

这不是非常安全的版本,但由于http2已经是二进制的,所以可能会工作一段时间。要创建和使用安全方式,您需要签署证书并在服务器和客户端中使用它。一个良好的示例在这里

此外,我建议重用通道,因为创建新通道很昂贵。Http2擅长在一个流上保持多个客户端。您可以重新创建客户端,这是一项便宜的操作。


来自微软的小更新https://learn.microsoft.com/en-us/aspnet/core/grpc/client?view=aspnetcore-3.1

目前在Xamarin上使用Grpc.Net.Client通过HTTP / 2调用gRPC尚未得到支持。我们正在努力改善将来Xamarin版本中的HTTP / 2支持。 Grpc.Core和gRPC-Web是可行的替代方案,今天就可以运行。


谢谢!实际上,Grpc.Core库是有效的。这是因为它是核心C++ grpc库的.NET包装器,因此不依赖于托管的SocketsHttpHandler。 - Kavinda Gayashan
然而,我会保持这个问题一段时间,以便有人可以指出为什么Http2连接与托管处理程序不起作用。实际上,本地包装库似乎添加了更多字节,并将我的apk大小增加了20 MB以上。希望在发布配置中可以减少这个问题。 - Kavinda Gayashan
关于安全性方面,我正在使用来自LetsEncrypt的免费证书进行保护。 - Kavinda Gayashan
@KavindaGayashan,我无法使其始终工作,DNS地址无法解析。你有这方面的经验吗? - carlcrol
@carlcrol 抱歉,我不记得看到过 DNS 问题。 - Kavinda Gayashan
@KavindaGayashan 你好,你能提供一些样例吗?我无法让它正常工作。 - carlcrol

1
我找到了解决这个问题的方法。Grpc不支持Xamarin、UWP和Unity,必须使用gRPC-Web代替。 Grpc-web 请参考Grpc的支持平台

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接