• .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();
            }
        }
    

  • 相关阅读:
    零基础入门深度学习(1)
    RxJava 复杂场景 Schedulers调度
    Kotlin 学习
    Cordova CrossWalk
    Android Studio工程导入另一个工程作为lib
    Android 数据存储相关
    Android Activity 生命周期中onStart()和onResume()的区别
    反省与规划
    Android 依赖注入 ButterKnife 基本使用
    Android Socket 相关
  • 原文地址:https://www.cnblogs.com/xiaoch/p/13417930.html
Copyright © 2020-2023  润新知