我尝试从控制台应用程序调用不安全的 (http) GRPC 服务(GRPC 服务和控制台客户端都在 docker 中运行),但出现以下异常:
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|281_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken)
at Grpc.Net.Client.Balancer.Internal.SocketConnectivitySubchannelTransport.TryConnectAsync(ConnectContext context)")'
尽管 StatusCode="Unavailable"
我可以确认该服务正在响应请求,因为我可以毫无问题地从 Postman 调用该服务。
我的docker-compose.override.yml
文件如下:
version: '3.4'
services:
grpcservice:
container_name: grpcservice
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "8000:80"
#- "8001:443"
networks:
- grpc-network
grpcclient:
container_name: grpcclient
environment:
- ASPNETCORE_ENVIRONMENT=Development
- "GrpcServiceUrl=http://grpcservice:8000"
networks:
- grpc-network
depends_on:
- grpcservice
networks:
grpc-network:
external: false
我的 GRPC 客户端的代码(控制台应用程序中的 Program.cs
)如下:
public static void CallGrpcService()
{
string serviceUrl = System.Environment.GetEnvironmentVariable("GrpcServiceUrl");
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var channel = GrpcChannel.ForAddress(serviceUrl);
var client = new Greeter.GreeterClient(channel);
var reply = client.SayHello(new HelloRequest { Name = "GreeterClient" });
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
完整的解决方案以及 docker 和 compose 文件 are in this repo in my github
有人可以帮我解决这个问题吗?
最佳答案
我已经成功执行了问题的 git 存储库中提供的代码,但只是在应用了以下修改之后:
将 Kestrel 配置为监听任何 IP 以及
80
以外的端口:builder.WebHost.ConfigureKestrel(options => { // Setup a HTTP/2 endpoint without TLS. options.ListenAnyIP(8000, o => o.Protocols = HttpProtocols.Http2); });
在
docker-compose.override.yml
中,grpcservice
应该有端口映射:ports: - "8000:8000"
为了更轻松地设置,我删除了卷定义,因为安全传输不是讨论的主题。
从客户端删除了
Http2UnencryptedSupport
开关,因为 .net 5 或更高版本中不再需要它。更多详情可查看here .
这是 docker compose 的输出:
Creating grpcservice ... done
Creating grpcclient ... done
Attaching to grpcservice, grpcclient
grpcservice | warn: Microsoft.AspNetCore.Server.Kestrel[0]
grpcservice | Overriding address(es) 'https://+:443, http://+:80'. Binding to endpoints defined via IConfiguration and/or UseKestrel() instead.
grpcservice | info: Microsoft.Hosting.Lifetime[14]
grpcservice | Now listening on: http://[::]:8000
grpcservice | info: Microsoft.Hosting.Lifetime[0]
grpcservice | Application started. Press Ctrl+C to shut down.
grpcservice | info: Microsoft.Hosting.Lifetime[0]
grpcservice | Hosting environment: Development
grpcservice | info: Microsoft.Hosting.Lifetime[0]
grpcservice | Content root path: /app
grpcclient | Greeting: Hello GreeterClient
grpcclient exited with code 0
关于c# - 调用在docker中运行的不安全的GRPC服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74296197/