我正在尝试从一个gRPC应用程序调用一个使用ASP.NET核心在.NET 5上构建的Xamarin.Forms服务。
我在服务器端使用Grpc.AspNetCore 2.35.0,在应用程序库(.NETStandard 2.1)中使用Grpc.Net.Client 2.35.0。
当尝试从客户端调用服务时,我得到了一个异常:
Exception caught: MyException: An unknown error happened
---> Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. AuthenticationException: Authentication failed, see inner exception. TlsException: CertificateUnknown", DebugException="System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> Mono.Security.Interface.TlsException: CertificateUnknown
at Mono.AppleTls.AppleTlsContext.EvaluateTrust () [0x000bf] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/System/Mono.AppleTls/AppleTlsContext.cs:306
[… SNIP …]
我认为这与自签名证书有关。我使用的是使用dotnet dev-certs https
工具创建的开发人员证书。
我尝试按照建议的here向创建的通道添加自定义处理程序
GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpHandler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback =
HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
}
});
还有另一个建议:
AppContext.SetSwitch(
"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
GrpcChannel.ForAddress("http://localhost:5000");
但这两种方法都会导致另一个异常(可能是因为这将使用不支持HTTP2.0的旧HttpClientHandler实现):
Exception caught: MyException: An unknown error happened
---> Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Request protocol 'HTTP/1.1' is not supported.")
我还尝试通过创建自定义CA +证书并在iOS模拟器中安装根证书来绕过自签名证书。但同样的结果也发生了。我不确定这在Android上是否会有所不同,因为我无法在仿真器上安装根证书。
如何在开发服务器上使用带有Xamarin.Forms的gRPC?
发布于 2021-05-01 18:15:45
我已经修复了上面的异常,改变我的实现来匹配这个:https://techblog.livongo.com/implementing-grpc-in-a-xamarin-mobile-project/块。
更详细地说:
我已经添加了对Grpc.Core、Grpc.Tools、Grpc.Net.Common、Grpc.Net.Client、Grpc.Core.Api;的引用
credentials)); credentials = CallCredentials.FromInterceptor((context,metadata) => Task.CompletedTask);返回新通道(“”,ChannelCredentials.Create(新SslCredentials(),var
https://stackoverflow.com/questions/66162942
复制相似问题