Grpc.Core.RpcException 从 .NET MAUI 应用程序调用 gRPC 服务时

问题描述 投票:0回答:2

我开发了一个简单的 ASP .NET 6 后端服务器,它通过 gRPC 提供服务。我还编写了一个基本的 WPF 桌面应用程序和一个简单的 .NET MAUI 应用程序(为 Android 设备配置)作为客户端应用程序。

我开始这样的服务:

public static IHostBuilder CreateHostBuilder(string[] args)
{
    var configuration = ServiceFactory.Instance.GetConfiguration();

    return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.ConfigureKestrel(options =>
        {
            options.Listen(configuration.IPAddress, configuration.HttpPort);
            options.Listen(configuration.IPAddress, configuration.HttpsPort, configure => configure.UseHttps());
        });

        webBuilder.UseStartup<Startup>();
    });
}

服务器应用程序启动精美。

桌面客户端工作

当我启动我的 WPF 桌面应用程序时,我使用以下代码连接到服务器并运行最基本的服务功能:Ping。它是一个始终返回有效响应对象的函数,它用作测试服务器是否处于活动状态,我还可以测试一般服务调用是否有效。

_grpcChannel = GrpcChannel.ForAddress("https://127.0.0.1:5005/", new GrpcChannelOptions()
{
    MaxReceiveMessageSize = 16 * 1024 * 1024,
    MaxSendMessageSize = 16 * 1024 * 1024,
    HttpHandler = new HttpClientHandler
    {
        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
    }
});

_authenticationClient = new AuthenticationClient(_grpcChannel);

_authenticationClient.Ping(new PingRequest());

手机客户端打不开

这完全符合预期。但是,当我在我的 .NET MAUI 应用程序中使用下面的代码时,它失败了。

_grpcChannel = GrpcChannel.ForAddress("http://127.0.0.1:5000/", new GrpcChannelOptions()
{
    MaxReceiveMessageSize = 16 * 1024 * 1024,
    MaxSendMessageSize = 16 * 1024 * 1024
});

_authenticationClient = new AuthenticationClient(_grpcChannel);

_authenticationClient.Ping(new PingRequest());

我使用 HTTP 而不是 HTTPS,因为没有有效 SSL 证书的 HTTPS 显然存在问题,例如当你在本地测试时。我读过这个here.

创建 gRPC 通道在我的 .NET MAUI 应用程序中确实有效,我还可以创建我的 AuthenticationClient 实例。但是,当我调用 Ping 服务功能时,我得到了这个。

{Grpc.Core.RpcException: Status(StatusCode="Unavailable", Detail="Error connecting to subchannel.", DebugException="System.Net.Sockets.SocketException (111): Connection refused
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|277_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
   at Grpc.Net.Client.Balancer.Internal.SocketConnectivitySubchannelTransport.TryConnectAsync(ConnectContext context) in /_/src/Grpc.Net.Client/Balancer/Internal/SocketConnectivitySubchannelTransport.cs:line 140")
   at Grpc.Net.Client.Balancer.Internal.ConnectionManager.PickAsync(PickContext context, Boolean waitForReady, CancellationToken cancellationToken) in /_/src/Grpc.Net.Client/Balancer/Internal/ConnectionManager.cs:line 352
   at Grpc.Net.Client.Balancer.Internal.BalancerHttpHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) in /_/src/Grpc.Net.Client/Balancer/Internal/BalancerHttpHandler.cs:line 109
   at Grpc.Net.Client.Internal.GrpcCall`2.<RunCall>d__73[[Engine.Server.Contracts.PingRequest, Engine.Server.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[Engine.Server.Contracts.PingResponse, Engine.Server.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() in /_/src/Grpc.Net.Client/Internal/GrpcCall.cs:line 493
   at Grpc.Net.Client.Internal.HttpClientCallInvoker.BlockingUnaryCall[PingRequest,PingResponse](Method`2 method, String host, CallOptions options, PingRequest request) in /_/src/Grpc.Net.Client/Internal/HttpClientCallInvoker.cs:line 116
   at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[PingRequest,PingResponse](PingRequest req, ClientInterceptorContext`2 ctx) in /_/src/Grpc.Core.Api/Interceptors/InterceptingCallInvoker.cs:line 51
   at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[PingRequest,PingResponse](PingRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation) in /_/src/Grpc.Core.Api/ClientBase.cs:line 174
   at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[PingRequest,PingResponse](Method`2 method, String host, CallOptions options, PingRequest request) in /_/src/Grpc.Core.Api/Interceptors/InterceptingCallInvoker.cs:line 48
   at Engine.Server.Contracts.Authentication.AuthenticationClient.Ping(PingRequest request, CallOptions options) in [a path]\obj\Debug\net6.0\AuthenticationGrpc.cs:line 316
   at Engine.Server.Contracts.Authentication.AuthenticationClient.Ping(PingRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) in [a path]\obj\Debug\net6.0\AuthenticationGrpc.cs:line 306

不幸的是,网络研究并没有透露太多,我对 .NET MAUI 开发还很陌生。非常感谢任何帮助。

c# sockets grpc maui
2个回答
0
投票

正确答案由 Jason 作为对我的原始帖子的评论给出。虽然一切都在我的机器上本地运行以进行测试,但我需要提供实际的 IP 地址才能使其适用于 Android 模拟器。谢谢你,Jason.


0
投票

10.0.2.2
是 Android Emulator 的 loopback 地址。因此,要使其在模拟器中运行,您需要使用:

_grpcChannel = GrpcChannel.ForAddress("http://10.0.2.2:5000/", new GrpcChannelOptions()
{
    MaxReceiveMessageSize = 16 * 1024 * 1024,
    MaxSendMessageSize = 16 * 1024 * 1024
});
© www.soinside.com 2019 - 2024. All rights reserved.