什么是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/