.net Core Grpc 客户端无法调用 Greeter 服务
Posted
技术标签:
【中文标题】.net Core Grpc 客户端无法调用 Greeter 服务【英文标题】:.net Core Grpc Client unable to call Greeter Service 【发布时间】:2020-08-14 18:50:23 【问题描述】:我已经看了很长时间了,浏览了互联网上所有不同的帖子,看看我是否能找到有同样问题的人,但不知何故,我似乎是唯一遇到这个问题的人。
我有一个 ASP.net Core 服务器运行 Grpc 的基本欢迎服务。 使用程序“BloomRPG”调用此服务器效果很好,并且响应时间极好。 但是,当我尝试从自己编写的(非常基本的)客户端执行相同操作时,出现以下错误:
在客户端:
dbug:Grpc.Net.Client.Internal.GrpcCall[1] 启动 gRPC 调用。方法类型:“一元”,URI:“https://www.MYSERVER.com:50005/greet.Greeter/SayHello”。 dbug:Grpc.Net.Client.Internal.GrpcCall[18] 发送消息。 trce:Grpc.Net.Client.Internal.GrpcCall[21] 将“TestService1.HelloRequest”序列化为 15 字节消息。 trce:Grpc.Net.Client.Internal.GrpcCall[19] 消息已发送。 失败:Grpc.Net.Client.Internal.GrpcCall[6] 启动 gRPC 调用时出错。 System.Net.Http.HttpRequestException:发送请求时出错。 ---> System.IO.IOException:响应提前结束。 在 System.Net.Http.HttpConnection.FillAsync() 在 System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(布尔 foldedHeadersAllowed) 在 System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage 请求,CancellationToken cancelToken) --- 内部异常堆栈跟踪结束 --- 在 System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage 请求,CancellationToken cancelToken) 在 System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection 连接,HttpRequestMessage 请求,布尔 doRequestAuth,CancellationToken 取消令牌) 在 System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage 请求,布尔 doRequestAuth,CancellationToken 取消令牌) 在 System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancelToken) 在 System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage 请求,CancellationToken cancelToken) 在 System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task
1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Grpc.Net.Client.Internal.GrpcCall
2.RunCall(HttpRequestMessage 请求, Nullable1 timeout) info: Grpc.Net.Client.Internal.GrpcCall[3] Call failed with gRPC error status. Status code: 'Internal', Message: 'Error starting gRPC call. HttpRequestException: An error occurred while sending the request. IOException: The response ended prematurely.'. dbug: Grpc.Net.Client.Internal.GrpcCall[4] Finished gRPC call. dbug: Grpc.Net.Client.Internal.GrpcCall[8] gRPC call canceled. Unhandled exception. Grpc.Core.RpcException: Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: An error occurred while sending the request. IOException: The response ended prematurely.", DebugException="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 System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(Task
1 sendTask, HttpRequestMessage 请求, CancellationTokenSource cts, Boolean disposeCts) 在 Grpc.Net.Client.Internal.GrpcCall2.RunCall(HttpRequestMessage request, Nullable
1 超时)") 在 C:\Users\MYUSERNAME\source\repos\grpc\TestgrpcClient\TestgrpcClient\Program.cs:line 64 中的 GrpcGreeterClient.Program.Main(String[] args) 在 GrpcGreeterClient.Program.(String[] args) s
在服务器上:
失败:Microsoft.AspNetCore.Server.Kestrel[0] HTTP/2 over TLS 不是在仅 HTTP/2 的端点上协商的。
由于我使用 BloomRPC 成功调用服务,我想问题出在我的客户端上:
客户端代码:
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var loggerFactory = LoggerFactory.Create(logging =>
logging.AddConsole();
logging.SetMinimumLevel(LogLevel.Trace);
);
var httpclient = new HttpClient();
httpclient.DefaultRequestVersion = new Version(2, 0);
using var channel = GrpcChannel.ForAddress("https://www.MYSERVER.com:50005",
new GrpcChannelOptions LoggerFactory = loggerFactory, HttpClient = httpclient);
var client = new Greeter.GreeterClient(channel);
var reply = await client.SayHelloAsync(
new HelloRequest Name = "GreeterClient" );
Console.WriteLine("Greeting: " + reply.Message);
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
有人知道我接下来可以尝试什么吗? 我觉得我已经用尽了所有的选择:(
【问题讨论】:
您遇到 TLS 身份验证错误。 TJS 1.0/1.1 已于 6 月停产,您必须使用 TLS 1.2 确保您拥有最新的 API 和 dll。旧版本不适用于 TLS 1.2。此外,如果您使用任何示例代码,请确保您拥有最新的代码。 好的,我已经添加了一个 httpclienthandler,它从上面强制在 httpclient 的构造函数中使用 TLS 1.2,但它给出了完全相同的错误。在电脑上转到 Internet 选项显示 TLS 1.2 已启用 不再编辑该评论?无论如何,我也觉得有必要添加我使用自包含客户端,所以这应该意味着对主机没有依赖关系吧?我尝试从另一台计算机执行并且客户端工作,但不是从第一台计算机执行。所以不是客户端的问题,而是计算机的问题? 使用像wireshark或fiddler这样的嗅探器,比较第一个工作请求和一个不工作的请求。存在错误或未设置的默认标头。 用 Wireshark 进行实验表明有公司代理服务器在干扰。我的猜测是,这会阻止我的客户建立良好的连接。我剩下的唯一问题是:为什么同一台电脑上的 BloomRPC 可以工作?不应该有同样的干扰吗? 【参考方案1】:感谢@jdweng,我找到了导致问题的原因。
强制公司代理服务器出现干扰,在 httpclienthandler 中设置 UseProxy = false 为我解决了这个问题,我现在可以毫无问题地调用我的 gRPC 服务器!
【讨论】:
以上是关于.net Core Grpc 客户端无法调用 Greeter 服务的主要内容,如果未能解决你的问题,请参考以下文章
[.Net Core] - 在 .NET Core 中创建 gRPC 服务端和客户端