.net core gRPC 一元,流通信 --- (單工 雙工)


#.NET 客戶端調用 gRPC 服務的四種通信方式

  • 一元調用
  • 客戶端流模式
  • 雙向流模式
  • 服務端流模式

一元調用

一元調用從客戶端發送請求消息開始。 服務完成後,將返回響應消息。

客戶端流模式

客戶端流式處理調用在客戶端發送消息的情況下啓動。 客戶端可以選擇發送發送消息RequestStream.WriteAsync。 當客戶端已經完成發送消息RequestStream.CompleteAsync時,應調用來通知服務。 當服務返回響應消息時,調用完成。

雙向流模式

雙向流式處理調用在客戶端發送消息的情況下啓動。 客戶端可以選擇通過RequestStream.WriteAsync發送消息。 可以通過或ResponseStream.ReadAllAsync()訪問從服務流式處理ResponseStream.MoveNext()的消息。 當沒有更多消息時ResponseStream ,雙向流式處理調用完成。

服務端流模式

服務器流式處理調用會從客戶端發送請求消息開始。 ResponseStream.MoveNext()讀取從服務傳輸的消息。 ResponseStream.MoveNext() 返回false時,服務器流調用已完成。

代碼 Protos

syntax = "proto3";

option csharp_namespace = "GrpcService1";

import "google/protobuf/empty.proto";
package Count;

service Counter{
	rpc AddStream(stream NumberRequest) returns (ResultReply);
	rpc Add(TwoNumberRequest) returns (ResultReply);
	rpc AddTwoStream(stream NumberRequest) returns (stream ResultReply);
	rpc GetInfo(google.protobuf.Empty) returns (ResultReply);
}

message TwoNumberRequest{
	int32 num1=1;
	int32 num2=2;
}

message NumberRequest{
	int32 num=1;
}

message ResultReply{
	int32 num=1;
}

代碼 服務端

   public class CountService : Counter.CounterBase
    {
        private readonly ILogger<CountService> _logger;
        public CountService(ILogger<CountService> logger)
        {
            _logger = logger;
        }
        //一元請求
        public override Task<ResultReply> Add(TwoNumberRequest request, ServerCallContext context)
        {
            return Task.FromResult(new ResultReply() { Num = request.Num1 + request.Num2 });
        }

        /// <summary>
        /// 雙向流請求
        /// </summary>
        /// <param name="requestStream"></param>
        /// <param name="responseStream"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task AddTwoStream(IAsyncStreamReader<NumberRequest> requestStream, IServerStreamWriter<ResultReply> responseStream, ServerCallContext context)
        {
            int result = 0;
            while (await requestStream.MoveNext())
            {
                result += requestStream.Current.Num;
                await responseStream.WriteAsync(new ResultReply() { Num = result });
                await Task.Delay(1000);
            }
            await responseStream.WriteAsync(new ResultReply() { Num = result*1000 }); 
        }

        /// <summary>
        /// 客戶端流程求
        /// </summary>
        /// <param name="requestStream"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public override async Task<ResultReply> AddStream(IAsyncStreamReader<NumberRequest> requestStream, ServerCallContext context)
        {
            int result = 0;
            while (await requestStream.MoveNext())
            {
                result += requestStream.Current.Num;
            }
            return await Task.FromResult(new ResultReply() { Num = result });
        }

        public override Task<ResultReply> GetInfo(Empty request, ServerCallContext context)
        {
            return base.GetInfo(request, context);
        }
    }

代碼 客戶端

  class Program
    {
        static async System.Threading.Tasks.Task Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = new GrpcService1.Counter.CounterClient(channel);
            Console.WriteLine("一元請求");
            var result = client.Add(new GrpcService1.TwoNumberRequest() { Num1 = 1, Num2 = 1 });
            Console.WriteLine($"一元請求結果{result.Num}");
            Console.WriteLine("-----------------------");
            Console.WriteLine("客戶端流請求");
            var clientStream = client.AddStream();
            for (var i = 0; i < 10; i++)
            {
                await clientStream.RequestStream.WriteAsync(new GrpcService1.NumberRequest() { Num = i });
            }
            clientStream.RequestStream.CompleteAsync();
            var resut1 = await clientStream;
            Console.WriteLine($"客戶端流請求結果{resut1.Num}");
            Console.WriteLine("-----------------------");
            Console.WriteLine("雙向流");
            var doubleStream = client.AddTwoStream();
            Task.Run(async () =>
            {
                await foreach (var resp in doubleStream.ResponseStream.ReadAllAsync())
                {
                    Console.WriteLine($"中間結果:{resp.Num}");
                }
            });
            for (var i = 0; i < 10; i++)
            {
               await doubleStream.RequestStream.WriteAsync(new GrpcService1.NumberRequest() { Num = i });
            }
            doubleStream.RequestStream.CompleteAsync();

            Console.ReadLine();
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章