从 .Net Framework 客户端调用 gRPC 服务器时出现异常
Exception when calling gRPC server from .Net Framework client
我有一个在 .Net Core 中实现的 gRPC 服务器,我想与 .Net Framework 中的控制台应用程序联系 运行。
这是该问题的工作回购:
https://github.com/q-bertsuit/grpc-framework-core-issue
以下 .Net Core 客户端工作正常:
class Program
{
static async Task Main(string[] args)
{
var input = new MyModel();
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Test.TestClient(channel);
var reply = await client.SetTestAsync(input);
Console.ReadLine();
}
}
以下 .Net Framework 客户端抛出异常:
class Program
{
static void Main(string[] args)
{
Channel channel = new Channel("https://localhost:5001", ChannelCredentials.Insecure);
var client = new Test.TestClient(channel);
MyModel request = new MyModel();
var reply = client.SetTest(request);
channel.ShutdownAsync().Wait();
Console.ReadLine();
}
}
发送请求时出现以下异常:
Grpc.Core.RpcException: 'Status(StatusCode="Unavailable", Detail="DNS
resolution failed for service: https://localhost:5001",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{"created":"@1600333768.055000000","description":"Resolver transient
failure","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolving_lb_policy.cc","file_line":215,"referenced_errors":[{"created":"@1600333768.055000000","description":"DNS
resolution failed for service:
https://localhost:5001","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.cc","file_line":378,"grpc_status":14,"referenced_errors":[{"created":"@1600333768.055000000","description":"C-ares
status is not ARES_SUCCESS qtype=A name=https://localhost:5001
is_balancer=0: Could not contact DNS
servers","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":287,"referenced_errors":[{"created":"@1600333768.055000000","description":"C-ares
status is not ARES_SUCCESS qtype=AAAA name=https://localhost:5001
is_balancer=0: Could not contact DNS
servers","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":287}]}]}]}")'
在服务器上我得到这个错误:
dbug: Microsoft.AspNetCore.Server.Kestrel[17]
Connection id "0HM2QU64LCR9J" bad request data: "Unrecognized HTTP version: 'HTTP/2.0'"
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException:
Unrecognized HTTP version: 'HTTP/2.0' at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser1.RejectUnknownVersion(Byte* version, Int32 length) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser
1.ParseRequestLine(TRequestHandler
handler, Byte* data, Int32 length) at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser1.ParseRequestLine(TRequestHandler handler, ReadOnlySequence
1& buffer, SequencePosition& consumed,
SequencePosition& examined) at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser1.Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, ReadOnlySequence
1& buffer, SequencePosition& consumed,
SequencePosition& examined) at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TakeStartLine(ReadOnlySequence1& buffer, SequencePosition& consumed, SequencePosition& examined) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.ParseRequest(ReadOnlySequence
1&
buffer, SequencePosition& consumed, SequencePosition& examined) at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult
result, Boolean& endConnection) at
Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication1 application) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication
1
application) dbug: Microsoft.AspNetCore.Server.Kestrel[10]
Connection id "0HM2QU64LCR9J" disconnecting. dbug: Microsoft.AspNetCore.Server.Kestrel[2]
Connection id "0HM2QU64LCR9J" stopped. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6]
Connection id "0HM2QU64LCR9J" received FIN. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7]
Connection id "0HM2QU64LCR9J" sending FIN because: "The Socket transport's send loop completed gracefully."
按照建议在 Kestrel 中添加了 Http/2 支持,但仍然出现错误:
Grpc.Core.RpcException: 'Status(StatusCode="Unknown", Detail="Received
http2 header with status: 307",
DebugException="Grpc.Core.Internal.CoreErrorDetailException:
{"created":"@1600342649.633000000","description":"Received http2
:status header with non-200 OK
status","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\http\client\http_client_filter.cc","file_line":130,"grpc_message":"Received
http2 header with status: 307","grpc_status":2,"value":"307"}")'
我不相信 Channel
的构造函数参数期望值是 URI 格式;你最好的选择可能是:
Channel channel = new Channel("localhost", 5001, ChannelCredentials.Insecure)
虽然它可能也可以用作:
Channel channel = new Channel("localhost:5001", ChannelCredentials.Insecure);
我通过关注 this answer
使其正常工作
我有一个在 .Net Core 中实现的 gRPC 服务器,我想与 .Net Framework 中的控制台应用程序联系 运行。
这是该问题的工作回购:
https://github.com/q-bertsuit/grpc-framework-core-issue
以下 .Net Core 客户端工作正常:
class Program
{
static async Task Main(string[] args)
{
var input = new MyModel();
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Test.TestClient(channel);
var reply = await client.SetTestAsync(input);
Console.ReadLine();
}
}
以下 .Net Framework 客户端抛出异常:
class Program
{
static void Main(string[] args)
{
Channel channel = new Channel("https://localhost:5001", ChannelCredentials.Insecure);
var client = new Test.TestClient(channel);
MyModel request = new MyModel();
var reply = client.SetTest(request);
channel.ShutdownAsync().Wait();
Console.ReadLine();
}
}
发送请求时出现以下异常:
Grpc.Core.RpcException: 'Status(StatusCode="Unavailable", Detail="DNS resolution failed for service: https://localhost:5001", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1600333768.055000000","description":"Resolver transient failure","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolving_lb_policy.cc","file_line":215,"referenced_errors":[{"created":"@1600333768.055000000","description":"DNS resolution failed for service: https://localhost:5001","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\dns_resolver_ares.cc","file_line":378,"grpc_status":14,"referenced_errors":[{"created":"@1600333768.055000000","description":"C-ares status is not ARES_SUCCESS qtype=A name=https://localhost:5001 is_balancer=0: Could not contact DNS servers","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":287,"referenced_errors":[{"created":"@1600333768.055000000","description":"C-ares status is not ARES_SUCCESS qtype=AAAA name=https://localhost:5001 is_balancer=0: Could not contact DNS servers","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\resolver\dns\c_ares\grpc_ares_wrapper.cc","file_line":287}]}]}]}")'
在服务器上我得到这个错误:
dbug: Microsoft.AspNetCore.Server.Kestrel[17] Connection id "0HM2QU64LCR9J" bad request data: "Unrecognized HTTP version: 'HTTP/2.0'" Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Unrecognized HTTP version: 'HTTP/2.0' at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser
1.RejectUnknownVersion(Byte* version, Int32 length) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser
1.ParseRequestLine(TRequestHandler handler, Byte* data, Int32 length) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser1.ParseRequestLine(TRequestHandler handler, ReadOnlySequence
1& buffer, SequencePosition& consumed, SequencePosition& examined) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser1.Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, ReadOnlySequence
1& buffer, SequencePosition& consumed, SequencePosition& examined) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TakeStartLine(ReadOnlySequence1& buffer, SequencePosition& consumed, SequencePosition& examined) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.ParseRequest(ReadOnlySequence
1& buffer, SequencePosition& consumed, SequencePosition& examined) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication1 application) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication
1 application) dbug: Microsoft.AspNetCore.Server.Kestrel[10] Connection id "0HM2QU64LCR9J" disconnecting. dbug: Microsoft.AspNetCore.Server.Kestrel[2] Connection id "0HM2QU64LCR9J" stopped. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[6] Connection id "0HM2QU64LCR9J" received FIN. dbug: Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets[7] Connection id "0HM2QU64LCR9J" sending FIN because: "The Socket transport's send loop completed gracefully."
按照建议在 Kestrel 中添加了 Http/2 支持,但仍然出现错误:
Grpc.Core.RpcException: 'Status(StatusCode="Unknown", Detail="Received http2 header with status: 307", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1600342649.633000000","description":"Received http2 :status header with non-200 OK status","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\http\client\http_client_filter.cc","file_line":130,"grpc_message":"Received http2 header with status: 307","grpc_status":2,"value":"307"}")'
我不相信 Channel
的构造函数参数期望值是 URI 格式;你最好的选择可能是:
Channel channel = new Channel("localhost", 5001, ChannelCredentials.Insecure)
虽然它可能也可以用作:
Channel channel = new Channel("localhost:5001", ChannelCredentials.Insecure);
我通过关注 this answer
使其正常工作