简介
grpc是由google公司开发的一个高性能、开源和通用的RPC框架,采用HTTP/2通信。
1.gRPC的传输使用http/2支持双向流。
2.支持多语言,例如java、go、php、net、node等多种语言.
3.gRPC支持多平台
4.性能好,效率高
1.HTTP/2
HTTP/2 提供了连接多路复用、双向流、服务器推送、请求优先级、首部压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU,帮助移动设备延长电池寿命等。gRPC 的协议设计上使用了HTTP2 现有的语义,请求和响应的数据使用HTTP Body 发送,其他的控制信息则用Header 表示。
使用
以下演示基于netcore2.2进行创建运行
运行前准备
因为netcore不会生成依赖包,所以需要先新建一个net framework的类库程序把需要用到的文件下载来
1.新建net framework程序并且安装grpc.tools
2.安装成功之后项目文件夹里会生成一个packages文件,在这里找到我们所需要的工具(x86还64请根据自己电脑自行选择)
1.环境准备
- GrpcClient 命令行程序
- GrpcLibray 类库程序
- GrpcServer 命令行程序
2.安装项目依赖
GrpcClient和GrpcLibray和GrpcServer 都需要安装通用的插件
install-package Grpc
install-package Goole.Protobuf
3.在GrpcLibray程序当中把前面我们用netframework添加的exe文件添加到该项目当中
4.添加命令行用来生成供其他程序调用的代码(hello.cmd)
protoc -I . --csharp_out ./server --grpc_out ./server --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe hello.proto
5.编写接口服务(hello.proto)
syntax = "proto3"; package GrpcLibrary; service HelloService{ rpc GetSum(GetMsgNumRequest) returns (GetMsgSumReply){}; rpc test(GetLotID)returns(GetLotAll){}; } message GetMsgNumRequest { int32 Num1 = 1; int32 Num2 = 2;} message GetMsgSumReply { int32 Sum = 1;} message GetLotID{int32 Num1=1;string s=2;} message GetLotAll{ enum Lists{ mes=0; wip=1; eap=2; dcs=3; } Lists t=1; repeated UserList user=2; } message UserList{ string userName=1; string pwd=2; }
6.在GrpcServer当中引用GrpcLibrary,并且重写定义的方法
using Grpc.Core; using GrpcLibrary; using System; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; namespace GrpcServer { class Program { public class GrpcImpl : HelloService.HelloServiceBase { public override async Task<GetMsgSumReply> GetSum(GetMsgNumRequest request, ServerCallContext context) { var result = new GetMsgSumReply(); result.Sum = request.Num1 + request.Num2; return result; } public override async Task<GetLotAll> test(GetLotID request, ServerCallContext context) { var result = new GetLotAll(); string s = "这里一共有:"; if (request.Num1 == 1) { s += "1个字符"; } s += request.S; UserList userList = new UserList(); userList.UserName = "张三"; result.User.Add(userList); List<UserList> userLists = new List<UserList>(); result.User.AddRange(userLists); result.T = GetLotAll.Types.Lists.Wip; return result; } } private static Server _server; static void Main(string[] args) { _server = new Server { Services = {HelloService.BindService(new GrpcImpl()) }, Ports = { new ServerPort("localhost",8088,ServerCredentials.Insecure)} }; _server.Start(); Console.WriteLine("grpc ServerListening On Port 8088"); Console.WriteLine("任意键退出..."); Console.ReadKey(); _server?.ShutdownAsync().Wait(); } } }
7.grpcClient客户端也需要引用GrpcLibrary
using Grpc.Core; using GrpcLibrary; using System; using System.Collections.Generic; using System.Text; namespace GrpcClient { public static class HelloClient { private static Channel _channel; private static HelloService.HelloServiceClient _client; static HelloClient() { _channel = new Channel("localhost:8088",ChannelCredentials.Insecure); _client = new HelloService.HelloServiceClient(_channel); } public static GetMsgSumReply getSum(int num1, int num2) { return _client.GetSum(new GetMsgNumRequest { Num1=num1,Num2=num2}); } public static GetLotAll GetLotAll(int num1, string s) { return _client.test(new GetLotID { Num1 = num1, S = s }); } } }
8.客户端调用
using GrpcLibrary; using System; namespace GrpcClient { class Program { static void Main(string[] args) { GetMsgSumReply helloMsg = HelloClient.getSum(11,2) ; GetLotAll getLotAll = HelloClient.GetLotAll(132, "我是老哈哈哈哈"); Console.WriteLine("grpc Client Call GetSum():" + helloMsg.Sum); string user = string.Empty; foreach (var item in getLotAll.User) { user += item; } Console.WriteLine("grpc Client Call GetLotAll():" + user); Console.WriteLine("任意键退出..."); Console.ReadKey(); } } }
运行如下图所示,先运行服务器端,在运行客户端
源码地址:https://github.com/zhengyazhao/grpc.git