什么是gRPC
gRPC是google開源的一個高性能、跨語言的RPC框架,基於HTTP2協議,采用ProtoBuf 定義的IDL。
gRPC 的主要優點是:
- 現代高性能輕量級 RPC 框架。
- 協定優先 API 開發,默認使用協議緩沖區,允許與語言無關的實現。
- 可用於多種語言的工具,以生成強類型服務器和客戶端。
- 支持客戶端、服務器和雙向流式處理調用。
- 使用 Protobuf 二進制序列化減少對網絡的使用。
這些優點使 gRPC 適用於:
- 效率至關重要的輕量級微服務。
- 需要多種語言用於開發的 Polyglot 系統。
- 需要處理流式處理請求或響應的點對點實時服務。
更多介紹請前往 https://grpc.io/docs/guides/
開始
netcore3.0中已經加入了gRPC的模板項目.
1,打開vs2019,創建一個asp.net core web項目
2,選擇ASP.NET Core 3.0就會出現gRPC模板,點擊創建。
如果沒安裝core3的SDK請前往https://dotnet.microsoft.com/download/dotnet-core/3.0下載最新版本安裝,
如果你已經安裝了core 3.0的SDK卻還是無法顯示其選項,工具 > 選項 ,勾選“使用 .NET Core SDK 預覽版”
3,模板只有一個服務端項目,需要自行創建一個客戶端來做演示,創建一個.netcore的控制台程序即可。
客戶端需要安裝以下三個包
- Grpc.Core,包含C-core客戶端的C#API。
- Google.Protobuf,包含C#的protobuf消息API。
- Grpc.Tools,包含對protobuf文件的C#工具支持。
服務端代碼
greet.proto,proto相關語法只是,前往 https://developers.google.com/protocol-buffers/docs/proto3,可能需要梯子。
syntax = "proto3"; package Greet; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. message HelloRequest { string name = 1; enum Language{ en_us = 0; //枚舉必須以0開始 zh_cn = 1; } Language languageEnum = 2; } // The response message containing the greetings. message HelloReply { string message = 1; int32 num = 2; int32 adsa = 3; }
GreeterService
public class GreeterService : Greeter.GreeterBase { public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) { var greeting = string.Empty; switch (request.LanguageEnum) { case HelloRequest.Types.Language.EnUs: greeting = "Hello"; break; case HelloRequest.Types.Language.ZhCn: greeting = "你好"; break; } return Task.FromResult(new HelloReply { Message = $"{greeting} {request.Name}", Num = new Random().Next() }); } }
客戶端代碼
添加greet.proto文件,將Protos\greet.proto文件從服務端復制到客戶端項目。將greet.proto文件路徑添加到項目文件GrpcDemo.Client.csproj的<ItemGroup>節點內。
這里我們不復制,直接定位到相關路徑即可。
GrpcDemo.Client.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.7.0" /> <PackageReference Include="Grpc.Core" Version="1.20.1" /> <PackageReference Include="Grpc.Tools" Version="1.20.1"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <!-- Include支持*匹配 --> <!-- GrpcServices="Client"添加該屬性構建相關客戶端類文件(元數據) --> <Protobuf Include="..\GrpcDemo.Server\Protos\*.proto" GrpcServices="Client" /> </ItemGroup> </Project>
Program.cs
static async Task Main(string[] args) { var serverAddress = "localhost:50051"; //創建連接通道,端口80 var channel = new Channel(serverAddress, ChannelCredentials.Insecure); var client = new Greeter.GreeterClient(channel); //請求 var reply1 = await client.SayHelloAsync( new HelloRequest { Name = "wu", LanguageEnum = HelloRequest.Types.Language.EnUs }); Console.WriteLine($"{reply1.Message} Num:{reply1.Num}"); var reply2 = await client.SayHelloAsync( new HelloRequest { Name = "wu", LanguageEnum = HelloRequest.Types.Language.ZhCn }); Console.WriteLine($"{reply2.Message} Num:{reply2.Num}"); //使用完后應釋放資源 await channel.ShutdownAsync(); Console.WriteLine("已斷開連接"); Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }
運行
Demo地址 https://github.com/wwwu/GrpcDemo
參考文檔
https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0
https://developers.google.com/protocol-buffers/docs/proto3
https://grpc.io/docs/guides/