前些天gRPC 發布1.0 版本,代表着gRPC 已經正式進入穩定階段。
今天我們就來學習gRPC C# 。而且目前也已經支持.NET Core 可以實現完美跨平台。
傳統的.NET 可以通過Mono 來實現跨平台調用。
GitHub: https://github.com/grpc/grpc
官方文檔:使用 C# 的 gRPC 服務 | Microsoft Docs
參考文檔:http://doc.oschina.net/grpc
gRPC 簡單介紹:
gRPC是一個高性能、通用的開源RPC框架,其由Google主要面向移動應用開發並基於HTTP/2協議標准而設計,基於ProtoBuf(Protocol Buffers)序列化協議開發,且支持眾多開發語言。gRPC提供了一種簡單的方法來精確地定義服務和為iOS、Android和后台支持服務自動生成可靠性很強的客戶端功能庫。客戶端充分利用高級流和鏈接功能,從而有助於節省帶寬、降低的TCP鏈接次數、節省CPU使用、和電池壽命。
gRPC支持多種語言,並能夠基於語言自動生成客戶端和服務端功能庫。目前,在GitHub上已提供了C版本grpc、Java版本grpc-java 和 Go版本grpc-go,其它語言的版本正在積極開發中,其中 grpc支持C、C++、Node.js、Python、Ruby、Objective-C、PHP和C#等語言,grpc-java已經支持Android開發。
gRPC已經應用在Google的雲服務和對外提供的API中,其主要應用場景如下:
低延遲、高擴展性、分布式的系統
同雲服務器進行通信的移動應用客戶端
設計語言獨立、高效、精確的新協議
便於各方面擴展的分層設計,如認證、負載均衡、日志記錄、監控等參考文檔:
http://www.infoq.com/cn/news/2015/03/grpc-google-http2-protobuf
本篇文章主要講解傳統.NET 應用如何支持gRPC。
下面就正式開始。
新建項目
首先我們創建一個gRPCDemo 的類庫。
然后添加兩個控制台應用程序 gRPCServer gRPCClient。
最終項目結構如下:
定義服務
建好項目以后我們來定義服務
這里我們在gRPCDemo 項目里添加一個 helloworld.proto 內容如下:
下面主要定義一個gRPC 的服務里面有個 SayHello rpc 方法
syntax = "proto3"; package gRPCDemo; service gRPC { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
使用Grpc.Tools生成代碼
定義好服務以后我們就可以來生成代碼了。
首先需要添加引用:
在每個項目中添加上Grpc 及 Google.Protobuf
Install-Package Grpc
Install-Package Google.Protobuf
然后在gRPCDemo 項目中再添加上工具 Grpc.Tools
NuGet 命令行:
Install-Package Grpc.Tools
然后在命令行執行以下命令,注意執行命令的目錄為packages 的上層目錄
packages\Grpc.Tools.1.0.0\tools\windows_x86\protoc.exe -IgRPCDemo --csharp_out gRPCDemo gRPCDemo\helloworld.proto --grpc_out gRPCDemo --plugin=protoc-gen-grpc=packages\Grpc.Tools.1.0.0\tools\windows_x86\grpc_csharp_plugin.exe
執行完以后,在gRPCDemo 目錄下會多出Helloworld.cs 及 HelloworldGrpc.cs 類,將其包含至gRPCDemo 項目既可。
然后gRPCServer gRPCClient 分別都引用 gRPCDemo。
創建服務端及客戶端
下面我們來編寫服務端及客戶端
首先是服務端:
Program.cs
class gRPCImpl : gRPC.gRPCBase { // 實現SayHello方法 public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) { return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); } } class Program { const int Port = 9007; public static void Main(string[] args) { Server server = new Server { Services = { gRPC.BindService(new gRPCImpl()) }, Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } }; server.Start(); Console.WriteLine("gRPC server listening on port " + Port); Console.WriteLine("任意鍵退出..."); Console.ReadKey(); server.ShutdownAsync().Wait(); } }
服務端需要實現SayHello 方法。
然后是客戶端 Program.cs
class Program { static void Main(string[] args) { Channel channel = new Channel("127.0.0.1:9007", ChannelCredentials.Insecure); var client = new gRPC.gRPCClient(channel); var reply= client.SayHello(new HelloRequest { Name = "LineZero" }); Console.WriteLine("來自" + reply.Message); channel.ShutdownAsync().Wait(); Console.WriteLine("任意鍵退出..."); Console.ReadKey(); } }
然后我們將Client 和Server 都生成一下。
分別到對應的目錄執行,首先啟動gRPCServer ,然后執行gRPCClient。
成功進行通信了,實現了gRPC。
本文源碼GitHub:https://github.com/linezero/Blog/tree/master/gRPCDemo
如果你覺得本文對你有幫助,請點擊“推薦”,謝謝。
出處:https://www.cnblogs.com/linezero/p/grpc.html
說明一下:
這里參數需要詳細說明一下(摘抄自:入門干貨之Grpc的.Net 封裝-MagicOnion),在這里卡了很長時間:
1. -I 指定一個或者多個目錄,用來搜索.proto文件的,如果不指定,那就是當前目錄,因為-I已經指定了。
2、 --csharp_out 用來生成C#代碼,當然了還能cpp_out、java_out、javanano_out、js_out、objc_out、php_out、python_out、ruby_out 這時候你就應該知道,這玩意就是支持多語言的,才用的,生成一些文件,然后給各個語言平台調用。參數1是輸出路徑,參數2是proto的文件名或者路徑。
3、--grpc_out 到這里可能有人會懵逼,咋回事?C#不是有一個自己的輸出目錄么?怎么又一個輸出?
csharp_out是輸出類似於咱們平時寫的實體類,接口,定義之類的。生成的文件叫,額,就叫xxx.cs吧.
grpc_out是跟服務相關,創建,調用,綁定,實現相關。生成的玩意叫xxxGrpc.cs。 對比上個選項生成的文件名,大概能了解個十之八九吧。
4、--plugin=protoc-gen-grpc=grpc_csharp_plugin.exe 這個就是c#的插件,python有python的,java有java的。必須要指定它。
出處:https://blog.csdn.net/img_Guo/article/details/86096604
我自己測試使用的如下:請把下面的代碼保存到grpc.bat文件中
packages\Grpc.Tools.2.27.0\tools\windows_x86\protoc.exe -IGrpcTest.Lib --csharp_out GrpcTest.Lib GrpcTest.Lib\helloworld.proto --grpc_out GrpcTest.Lib --plugin=protoc-gen-grpc=packages\Grpc.Tools.2.27.0\tools\windows_x86\grpc_csharp_plugin.exe