C# 使用 grpc 問題匯總


grpc 是個跨平台的遠程調用框架,第一次在windows平台使用,有很多問題需要面對,下面做個匯總,以備檢查

跨平台

消息長度設置

出現的問題 1

客戶端出現異常

未經處理的異常:  Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="Max message size exceeded")
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 Grpc.Core.Internal.AsyncCall`2.UnaryCall(TRequest msg)
   在 Grpc.Core.Calls.BlockingUnaryCall[TRequest,TResponse](CallInvocationDetails`2 call, TRequest req)
   在 Grpc.Core.DefaultCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   在 Grpc.Core.Internal.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   在 Helloworld.Greeter.GreeterClient.GetUsers(SearchUserRequest request, CallOptions options) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\Greeter\HelloworldGrpc.cs:行號 148
   在 Helloworld.Greeter.GreeterClient.GetUsers(SearchUserRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\Greeter\HelloworldGrpc.cs:行號 144
   在 GreeterClient.Program.Main(String[] args) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\GreeterClient\Program.cs:行號 61

在服務端出現異常

W1024 09:50:02.749888 Grpc.Core.Server Exception while handling RPC. System.InvalidOperationException: Error sending status from server.
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   在 Grpc.Core.Internal.UnaryServerCallHandler`2.<HandleCall>d__0.MoveNext()
--- 引發異常的上一位置中堆棧跟蹤的末尾 ---
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 Grpc.Core.Server.<HandleCallAsync>d__11.MoveNext()

## 出現問題 2

在客戶端出現異常

未經處理的異常:  Grpc.Core.RpcException: Status(StatusCode=Internal, Detail="{"created":"@1477274209.883000000","description":"RST_STREAM","file":"c:\jenkins\workspace\gRPC_build_artifacts\architecture\x86\language\csharp\platform\windows\vsprojects\..\src\core\ext\transport\chttp2\transport\frame_rst_stream.c","file_line":107,"http2_error":2}")
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 Grpc.Core.Internal.AsyncCall`2.UnaryCall(TRequest msg)
   在 Grpc.Core.Calls.BlockingUnaryCall[TRequest,TResponse](CallInvocationDetails`2 call, TRequest req)
   在 Grpc.Core.DefaultCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   在 Grpc.Core.Internal.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method`2 method, String host, CallOptions options, TRequest request)
   在 Helloworld.Greeter.GreeterClient.GetUsers(SearchUserRequest request, CallOptions options) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\Greeter\HelloworldGrpc.cs:行號 148
   在 Helloworld.Greeter.GreeterClient.GetUsers(SearchUserRequest request, Metadata headers, Nullable`1 deadline, CancellationToken cancellationToken) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\Greeter\HelloworldGrpc.cs:行號 144
   在 GreeterClient.Program.Main(String[] args) 位置 E:\MyTest\grpc-1.0.x\examples\csharp\helloworld\GreeterClient\Program.cs:行號 71

在服務端出現異常

W1024 09:56:49.886636 Grpc.Core.Internal.UnaryServerCallHandler`2 Exception occured in handler. System.ArgumentException: 值不在預期的范圍內。
   在 Grpc.Core.Internal.UnaryServerCallHandler`2.<HandleCall>d__0.MoveNext()
W1024 09:56:49.889643 Grpc.Core.Server Exception while handling RPC. System.InvalidOperationException: Error sending status from server.
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   在 Grpc.Core.Internal.UnaryServerCallHandler`2.<HandleCall>d__0.MoveNext()
--- 引發異常的上一位置中堆棧跟蹤的末尾 ---
   在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   在 Grpc.Core.Server.<HandleCallAsync>d__11.MoveNext()

解決方法

出現這個問題是grpc對默認的消息大小(massage size)做了限制,限制的值在各個版本中還不太一樣,為了讓grpc的效率更高,開發者認為應該不要太大,4M比較合適。

但實際應用中,雖然可以規定編寫contract要合理,但是還會很多大的對象。

解決方法是手動設置messagesize的值。

問題1 是沒有在客戶端設置messagesize,接收到大的對象后客戶端無法解析。問題2 是在服務端沒有設置messagesize,服務端無法解析發送來的消息。

在服務端需要的代碼

 var options = new List<ChannelOption> { new ChannelOption(ChannelOptions.MaxMessageLength,int.MaxValue) }; Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure, options);

在客戶端需要的代碼

Server server = new Server(new List<ChannelOption> { new ChannelOption(ChannelOptions.MaxMessageLength, int.MaxValue) }) { Services = { Greeter.BindService(new GreeterImpl()) }, Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } }; 

到底這個值設置為多少合理,如果設置到int.MaxValue,對性能有什么影響,在后面使用中逐步體會。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM