Клиент c # Grpc Не удается подключиться к серверу Grpc, расположенному в контейнере Docker (для Windows) на локальном хосте - PullRequest
0 голосов
/ 22 сентября 2018

Я сделал простой Grpc Greeter Service вместе с клиентом.Когда служба размещается на локальном хосте, клиент может вызвать RPC и получить ответ.Но когда служба работает внутри док-контейнера на локальном хосте, клиент не может подключиться к службе.

** Сервер службы Grpc **

namespace GreeterServer
{
    class Program
    {
        private readonly static ManualResetEvent shutdown = new ManualResetEvent(false);
        static void Main(string[] args)
        {
            int port = 5000;
            Console.WriteLine("Hello World!");
            Server server = new Server{
                Services = {GreeterService.BindService(new GreeterController())},
                Ports = {new ServerPort("localhost", port, ServerCredentials.Insecure)}
            };
            server.Start();
            Console.WriteLine("Grpc Server started");
            Console.Read();
            shutdown.WaitOne();
        }
    }
}

** Dockerfile для службы Grpc **

FROM microsoft/dotnet:2.1-sdk as base
WORKDIR /app

COPY *.csproj .
RUN dotnet restore

COPY . .
RUN dotnet build -c Release -o out

FROM microsoft/dotnet:2.1-runtime
WORKDIR /app
COPY --from=base /app/out .
ENTRYPOINT ["dotnet", "GreeterServer.dll"]
EXPOSE 5000

** Клиент Grpc **

namespace GreeterClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("Hello World!");
                Channel channel = new Channel("127.0.0.1:5000", ChannelCredentials.Insecure);
                GreeterService.GreeterServiceClient client = new GreeterService.GreeterServiceClient(channel);
                HelloRequest request = new HelloRequest
                {
                    Message = "Hi From Client"
                };
                HelloResponse response = client.SayHello(request);
                Console.WriteLine(response.Message);
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }

        }
    }
}

** Stacktrace от клиента Grpc **

Grpc.Core.RpcException: Status(StatusCode=Unknown, Detail="Stream removed")
   at Grpc.Core.Internal.AsyncCall`2.UnaryCall(TRequest msg) in T:\src\github\grpc\src\csharp\Grpc.Core\Internal\AsyncCall.cs:line 75
   at Grpc.Core.DefaultCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request) in T:\src\github\grpc\src\csharp\Grpc.Core\DefaultCallInvoker.cs:line 46
   at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext`2 ctx) in T:\src\github\grpc\src\csharp\Grpc.Core\Interceptors\InterceptingCallInvoker.cs:line 51
   at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation) in T:\src\github\grpc\src\csharp\Grpc.Core\ClientBase.cs:line 174
   at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request) in T:\src\github\grpc\src\csharp\Grpc.Core\Interceptors\InterceptingCallInvoker.cs:line 48
   at Greeter.Proto.GreeterService.GreeterServiceClient.SayHello(HelloRequest request, CallOptions options) in F:\c#\GrpcPracticeWithDocker\GreeterClient\GrpcClasses\GreeterGrpc.cs:line 70
   at Greeter.Proto.GreeterService.GreeterServiceClient.SayHello(HelloRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) in F:\c#\GrpcPracticeWithDocker\GreeterClient\GrpcClasses\GreeterGrpc.cs:line 66
   at GreeterClient.Program.Main(String[] args) in F:\c#\GrpcPracticeWithDocker\GreeterClient\Program.cs:line 23

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Я сталкивался с той же проблемой.Но, наконец, это связано с настройкой прокси.GRPC использует конфигурацию среды "HTTP_PROXY" и "HTTPS_PROXY".К сожалению, мой сервер grpc работает в локальной сети, которая не требует прокси.Я пропустил определение переменной окружения "NO_PROXY".

Как только я добавил ip сервера grpc в NO_PROXY, он начал работать.

Примечание:

  1. Я могу заставить докер работать только с "localhost".Я не ограничил свой сервер grpc значением «0.0.0.0»
  2. . Я диагностировал проблему, включив ведение журнала трассировки GRPC.После включения трассировки вы должны использовать следующий код для отображения журналов в консоли.

ref: https://github.com/grpc/grpc/blob/master/TROUBLESHOOTING.md

GrpcEnvironment.SetLogger(new ConsoleLogger());
0 голосов
/ 17 октября 2018

(1) Не используйте localhost на вашем сервере GRPC внутри докера, он не будет работать, так как локальный хост с обратной связью не может быть достигнут извне докера, вам нужно прослушивать все интерфейсы, поэтому используйте «0.0.0.0», например.

Ports = {new ServerPort ("0.0.0.0", port, ServerCredentials.Insecure)}

Вот стек, относящийся к этой проблеме: Невозможно подключиться к серверу Go GRPCработает в локальном контейнере Docker

(2) У меня была такая же проблема.Я обнаружил, что проблема заключалась в том, что я не использовал интерактивную оболочку при использовании Docker Run или Docker Comose.Если вы используете Docker Run, вам нужно использовать команды -it, а для создания Docker вам нужно использовать stdin_open: true и tty: true.

Пример запуска Docker

docker run --name grpcserver -p 8081:8081 -it -d grpcserver

Пример создания Docker

version: '3'

services:
  web:
    container_name: mynginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 8080:80
  grpcserver:
    image: grpcserver
    container_name: grpcserver
    stdin_open: true
    tty: true
    build:
      context: .
      dockerfile: Dockerfile

Вот еще один стек, который говорит об этом: Интерактивная оболочка с использованием Docker Compose

Удачи!

...