gRPC支持4种流
  1. 简单 RPC(Unary RPC)
  2. 服务端流式 RPC (Server streaming RPC)
  3. 客户端流式 RPC (Client streaming RPC)
  4. 双向流式 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;
        }

 

 

posted on 2022-07-25 09:33  CRUDEngineer  阅读(173)  评论(0编辑  收藏  举报