gRPC支持4种流
- 简单 RPC(Unary RPC)
- 服务端流式 RPC (Server streaming RPC)
- 客户端流式 RPC (Client streaming RPC)
- 双向流式 RPC(Bi-directional streaming RPC)
1.简单RPC
proto文件:
syntax = "proto3"; option csharp_namespace = "GrpcDemoClients"; package mathUtilsPackage; // The greeting service definition. service MathUtils { // Sends a greeting rpc Add (AddRequest) returns (AddReply); } // The request message containing the user's name. message AddRequest { int32 left = 1; int32 right = 2; } // The response message containing the greetings. message AddReply { int32 total = 1; }
服务端代码:
using System.Threading.Tasks; using Grpc.Core; namespace GrpcDemoClients.Services { public class MathUtilsService:MathUtils.MathUtilsBase { public override Task<AddReply> Add(AddRequest request, ServerCallContext context) { return Task.FromResult(new AddReply { Total = request.Left + request.Right }); } } }
客户端代码:
private static async Task TestMathTotal() { using var channel = GrpcChannel.ForAddress(" https://localhost:5001"); var client = new MathUtils.MathUtilsClient(channel); var reply = await client.AddAsync(new AddRequest { Left=1, Right=2 }); Console.WriteLine("Return the value is:" + reply.Total); }
2.服务端流
proto文件:
syntax = "proto3"; option csharp_namespace = "GrpcDemoClients"; package serverRpcUtilsPackage; // The greeting service definition. service ServerRpcUtils { // Sends a greeting rpc SelfIncreaseServer(IntArrayModel) returns (stream BathTheCatResp); } message IntArrayModel{ repeated int32 Numbers=1;//集合 } message BathTheCatResp{ string Message=1; }
服务端代码:
using System; using System.Threading.Tasks; using Grpc.Core; namespace GrpcDemoClients.Services { public class ServerRpcService: ServerRpcUtils.ServerRpcUtilsBase { public async override Task SelfIncreaseServer(IntArrayModel request, IServerStreamWriter<BathTheCatResp> responseStream, ServerCallContext context) { foreach (var item in request.Numbers) { int number = item; Console.WriteLine($"This is {number} invoke"); await responseStream.WriteAsync(new BathTheCatResp() { Message = $"number++ ={++number}!" }); await Task.Delay(500);//此处主要是为了方便客户端能看出流调用的效果 } } } }
客户端代码:
private static async Task TestServerRpc() { using var channel = GrpcChannel.ForAddress(" https://localhost:5001"); var client = new ServerRpcUtils.ServerRpcUtilsClient(channel); var resp = new IntArrayModel(); for (int i = 0; i < 15; i++) { resp.Numbers.Add(i); } var bathCat = client.SelfIncreaseServer(resp); var bathCatRespTask = Task.Run(async () => { await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()) { Console.WriteLine(resp.Message); Console.WriteLine($"This is Response {Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine("**********************************"); } }); Console.WriteLine("客户端已发送完10个id"); //开始接收响应 await bathCatRespTask; }
3.客户端流式
proto文件:
syntax = "proto3"; option csharp_namespace = "GrpcDemoClients"; package serverRpcUtilsPackage; // The greeting service definition. service ServerRpcUtils { // Sends a greeting rpc SelfIncreaseClient(stream BathTheCatReq) returns (IntArrayModel); } message IntArrayModel{ repeated int32 Numbers=1;//集合 } message BathTheCatResp{ string Message=1; } message BathTheCatReq{ int32 Id=1; }
服务端代码:
public async override Task<IntArrayModel> SelfIncreaseClient(IAsyncStreamReader<BathTheCatReq> requestStream, ServerCallContext context) { IntArrayModel intArrayModel = new IntArrayModel(); while (await requestStream.MoveNext()) { intArrayModel.Numbers.Add(requestStream.Current.Id + 1); Console.WriteLine($"SelfIncreaseClient Number {requestStream.Current.Id} 获取到并处理."); Thread.Sleep(100); } return intArrayModel; }
客户端代码:
private static async Task TestClientRpc() { using var channel = GrpcChannel.ForAddress(" https://localhost:5001"); var client = new ServerRpcUtils.ServerRpcUtilsClient(channel); var bathCat = client.SelfIncreaseClient(); for (int i = 0; i < 10; i++) { await bathCat.RequestStream.WriteAsync(new BathTheCatReq() { Id = new Random().Next(0, 20) }); await Task.Delay(100); Console.WriteLine($"This is {i} Request {Thread.CurrentThread.ManagedThreadId}"); } Console.WriteLine("**********************************"); //发送完毕 await bathCat.RequestStream.CompleteAsync(); Console.WriteLine("客户端已发送完10个id"); Console.WriteLine("接收结果:"); foreach (var item in bathCat.ResponseAsync.Result.Numbers) { Console.WriteLine($"This is {item} Result"); } Console.WriteLine("**********************************"); }
4.双向流式 RPC
proto文件:
syntax = "proto3"; option csharp_namespace = "GrpcDemoClients"; package serverRpcUtilsPackage; // The greeting service definition. service ServerRpcUtils { // Sends a greeting rpc SelfIncreaseDouble(stream BathTheCatReq) returns ( stream BathTheCatResp); } message IntArrayModel{ repeated int32 Numbers=1;//集合 } message BathTheCatResp{ string Message=1; } message BathTheCatReq{ int32 Id=1; }
服务端代码:
public async override Task SelfIncreaseDouble(IAsyncStreamReader<BathTheCatReq> requestStream, IServerStreamWriter<BathTheCatResp> responseStream, ServerCallContext context) { while (await requestStream.MoveNext()) { Console.WriteLine($"SelfIncreaseDouble Number {requestStream.Current.Id} 获取到并处理."); await responseStream.WriteAsync(new BathTheCatResp() { Message = $"number++ ={requestStream.Current.Id + 1}!" }); await Task.Delay(500);//此处主要是为了方便客户端能看出流调用的效果 } }
客户端代码:
private static async Task TestDoubleRpc() { using var channel = GrpcChannel.ForAddress(" https://localhost:5001"); var client = new ServerRpcUtils.ServerRpcUtilsClient(channel); var bathCat = client.SelfIncreaseDouble(); var bathCatRespTask = Task.Run(async () => { await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()) { Console.WriteLine(resp.Message); Console.WriteLine($"This is Response {Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine("**********************************"); } }); for (int i = 0; i < 10; i++) { await bathCat.RequestStream.WriteAsync(new BathTheCatReq() { Id = new Random().Next(0, 20) }); await Task.Delay(100); Console.WriteLine($"This is {i} Request {Thread.CurrentThread.ManagedThreadId}"); Console.WriteLine("**********************************"); } //发送完毕 await bathCat.RequestStream.CompleteAsync(); Console.WriteLine("客户端已发送完10个id"); Console.WriteLine("接收结果:"); //开始接收响应 await bathCatRespTask; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南