【问题标题】:"The response ended prematurely" when connecting to insecure gRPC channel连接到不安全的 gRPC 通道时“响应提前结束”
【发布时间】:2020-01-22 22:37:27
【问题描述】:

我正在尝试与不安全的 gRPC 服务器建立连接。我正在使用 gRPC 在 Docker 容器内的两个进程之间进行通信,这就是我不需要任何加密或强身份验证的原因。

服务器按预期运行,我可以像这样使用 grpcurl 进行调用:

grpcurl -plaintext localhost:42652 SomeService.DoSomething

现在我正在尝试从 .Net Core 应用程序调用相同的 RPC 方法:

// Registration of the DI service
services.AddGrpcClient<DaemonService.DaemonServiceClient>(options => {
    // Enable support for unencrypted HTTP2
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

    options.Address = new Uri("http://localhost:42652");

    // Just a test, doesn't change anything.
    options.ChannelOptionsActions.Add(channelOptions => channelOptions.Credentials = ChannelCredentials.Insecure);
});

// Call
var reply = _someServiceClient.DoSomething(new Request());

但是最后一行的调用导致异常:

fail: Grpc.Net.Client.Internal.GrpcCall[6]
      Error starting gRPC call.
System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: The response ended prematurely.
   at System.Net.Http.HttpConnection.FillAsync()
   at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Grpc.Net.Client.Internal.GrpcCall`2.SendAsync(HttpRequestMessage request)
fail: Grpc.Net.Client.Internal.GrpcCall[3]
      Call failed with gRPC error status. Status code: 'Cancelled', Message: 'Error starting gRPC call.'.
fail: SomeNamespace.Session.Program[0]
      An error occured.
System.Net.Http.HttpRequestException: An error occurred while sending the request.
 ---> System.IO.IOException: The response ended prematurely.
   at System.Net.Http.HttpConnection.FillAsync()
   at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed)
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
   at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
   at Grpc.Net.Client.Internal.GrpcCall`2.SendAsync(HttpRequestMessage request)
   at Grpc.Net.Client.Internal.GrpcCall`2.GetResponseAsync()
   at Grpc.Net.Client.Internal.HttpClientCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext`2 ctx)
   at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext`2 context, BlockingUnaryCallContinuation`2 continuation)
   at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   at SomeNamespace.RpcServices.DaemonService.DaemonServiceClient.GetVncContainerEnvironment(EmptyRequest request, CallOptions options) in /src/SomeNamespace.RpcServices/obj/Release/netcoreapp3.0/Vnc-container-daemonGrpc.cs:line 98
   at SomeNamespace.RpcServices.DaemonService.DaemonServiceClient.GetVncContainerEnvironment(EmptyRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) in /src/SomeNamespace.RpcServices/obj/Release/netcoreapp3.0/Vnc-container-daemonGrpc.cs:line 94
   at SomeNamespace.Rpc.RpcEventListener.StartListening() in /src/SomeNamespace/Rpc/RpcEventListener.cs:line 32

你知道我要做什么不同的事情吗?我找不到太多关于建立这样的不安全连接的文档。

【问题讨论】:

    标签: c# .net .net-core grpc


    【解决方案1】:

    我自己找到了解决方法:

    当我将AppContext.SetSwitch 移动到AddGrpcClient 上方时,它可以工作。

    // Enable support for unencrypted HTTP2  
    AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
    
    // Registration of the DI service
    services.AddGrpcClient<DaemonService.DaemonServiceClient>(options => {
        options.Address = new Uri("http://localhost:42652");
        options.ChannelOptionsActions.Add(channelOptions => channelOptions.Credentials = ChannelCredentials.Insecure);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 2021-04-09
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 2013-10-17
      相关资源
      最近更新 更多