【问题标题】:"The server committed a protocol violation" exception is thrown when using grpc-net client and grpc (google's) server on an unsecured channel在不安全的通道上使用 grpc-net 客户端和 grpc(google 的)服务器时抛出“服务器违反协议”异常
【发布时间】:2023-02-14 03:59:34
【问题描述】:

我正在尝试在 .net 标准 2.0 项目上设置 grpc-net 客户端,该项目通过不安全的通道连接到运行 google 实现的 grpc 服务器。

服务器端运行在 .NET 6.0 控制台应用程序上,带有谷歌的 grpc 实现:

var server = new Grpc.Core.Server()
{
   Ports = { new ServerPort("localhost", 0, ServerCredentials.Insecure) },
   Services = { Greeter.BindService(new GreeterServer()) }
};
server.Start();

客户端作为 .net 4.7.2 控制台应用程序运行(使用服务器端口作为输入):

var channel = GrpcChannel.ForAddress("http://localhost:" + port, new GrpcChannelOptions
{
   HttpHandler = new GrpcWebHandler(new HttpClientHandler()),
   Credentials = ChannelCredentials.Insecure
});

var client = new Greeter.GreeterClient(channel);

客户端Channel创建抛出如下异常:

Grpc.Core.RpcException: 'Status(StatusCode="内部", 详细信息="错误 启动 gRPC 调用。 HttpRequestException: 发生错误 发送请求。 WebException:服务器提交了一个协议 违反。 Section=ResponseStatusLine", DebugException="System.Net.Http.HttpRequestException: 一个错误 发送请求时发生。 ---> System.Net.WebException: 的 服务器违反了协议。部分=响应状态行
在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context) 在 System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) --- 内部异常堆栈跟踪结束 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Grpc.Net.Client.Web.GrpcWebHandler.d__18.MoveNext() 中 //src/Grpc.Net.Client.Web/GrpcWebHandler.cs:line 166 --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
在 Grpc.Net.Client.Internal.GrpcCall`2.d__73.MoveNext() 中 /
/src/Grpc.Net.Client/Internal/GrpcCall.cs:line 493")'

【问题讨论】:

  • 请参阅以下内容:github.com/grpc/grpc-dotnet/issues/1552
  • @jdweng 感谢您提供链接。根据他们的回答,问题是客户端正在尝试使用 http 1.1,而服务器正在使用 http2。在我的例子中,服务器是谷歌的实现,AFAIK 根本不支持 http 1.1。是不是说grpc-net client就连不上google的grpc server了? (假设我不能使用最新的 windows 版本和设置 WinHttpHandler)
  • 您使用的是什么端口号? HTTPS 通常使用 443。因此如果问题与链接相同,则为 HTTP/HTTPS 和端口号的组合。服务器确定最低要求。所以它也取决于服务器。如果服务器需要 http2,则必须使用 http2。它服务器需要 TLS,您必须使用 TLS(HTTPS 而不是 HTTP)。如果您使用的是 TLS,则可能需要使用 1.2 或 1.3。 Net 4.7.2 在操作系统(不是 Net)中默认为 TLS,因此如果您可以使用浏览器访问站点,您可能也可以在 c# 中执行相同的操作。
  • 这是一个不安全的频道。服务器是一个控制台应用程序
  • 您可能需要使用 TLS。在客户端尝试使用 HTTPS 而不是 HTTP。服务器计算机可能需要 HTTPS,您无法更改服务器。

标签: c# grpc grpc-c# grpc-dotnet


【解决方案1】:

这个错误正是由于 here 描述的原因而发生的(在服务器使用 http2 时使用 http 1.1)至于你在 cmets 中的问题 - 是的 -这意味着 grpc-net 客户端将无法连接到 google 的 grpc 服务器在你使用它的方式。 当我需要连接到通过 HTTP 0.9 工作的 grpc 服务器时,我遇到了一个更复杂的情况,这是同样的异常。 我找到了方法。有一个使用native gRPC Core librarythe C# implementation 的实现。在这里您将获得创建频道的能力。对于您的情况,它看起来像:

    var channel = new Grpc.Core.Channel("localhost", port, ChannelCredentials.Insecure);
    var client = new Greeter.GreeterClient(channel);

请注意,因为它处于维护模式。 Here你可以看看。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 2020-10-18
    • 2018-04-12
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 2020-09-09
    • 2016-10-04
    相关资源
    最近更新 更多