grpc共有四种模式:一般模式、输入流式、输出流式、双向流式
该demo采用一个普通grpc例子和一个输出流式例子
entity.proto
syntax = "proto3"; package Grpc.Contract; message UserModel{ int32 Id = 1; string Name = 2; } message SearchModel{ int32 Id = 1; string Keywords = 2; } message ResultModel{ bool Success = 1; }
user.proto
syntax = "proto3"; import "entity.proto"; package Grpc.Contract; service User { rpc User(SearchModel) returns (UserModel){} } service Users{ rpc Users(SearchModel) returns (stream UserModel){} }
执行tool命令生成c#类文件 protoc.exe -I=. --csharp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_csharp_plugin.exe GetUser.proto
服务端代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Grpc.Contract; using Grpc.Core; namespace Grpc.Server { public class UserBll : User.UserBase { public override async Task<UserModel> User(SearchModel request, ServerCallContext context) { return await Task.FromResult(new UserModel { Id = 1, Name = "test1" }); } } public class UsersBll : Users.UsersBase { public async override Task Users(SearchModel request, IServerStreamWriter<UserModel> responseStream, ServerCallContext context) { var users = new List<UserModel> { new UserModel { Id = 1, Name = "test1" }, new UserModel { Id = 2, Name = "test2" }, new UserModel { Id = 3, Name = "test3" } }; foreach (var user in users) { await responseStream.WriteAsync(user); } } } }
启动服务端
using Grpc.Contract; using Grpc.Core; using Grpc.Server; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class Program { static void Main(string[] args) { const int port = 9725; Server server = new Server { Services = { User.BindService(new UserBll()), Users.BindService(new UsersBll()) }, Ports = { new ServerPort("127.0.0.1", port, ServerCredentials.Insecure) } }; server.Start(); Console.WriteLine("grpc server started at port " + port); Console.ReadLine(); } } }
客户端依然需要契约,由于此demo都是C#语言,所以契约使用同一个就行,否则按照对应语言生成契约
客户端代码
using Grpc.Contract; using Grpc.Core; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace GrpcConsoleApp { class Program { static void Main(string[] args) { var channel = new Channel("127.0.0.1:9725", ChannelCredentials.Insecure); var req = new User.UserClient(channel); var rsp = req.User(new SearchModel { Id = 1 }); var users = new List<UserModel>(); var usersSearch = new Users.UsersClient(channel); using (var usersResponse = usersSearch.Users(new SearchModel { Id = 1 })) { while (usersResponse.ResponseStream.MoveNext().Result) { users.Add(usersResponse.ResponseStream.Current); } } channel.ShutdownAsync().Wait(); Console.WriteLine(JsonConvert.SerializeObject(rsp)); Console.WriteLine(JsonConvert.SerializeObject(users)); } } }
参考宋米粒的博文,写的很详细 https://www.cnblogs.com/songjl/p/NETGRPC.html