zoukankan      html  css  js  c++  java
  • gRPC在 ASP.NET Core 中应用学习

    一、gRPC简介:

     gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。 gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建。它使用HTTP/2作为通信协议,使用 Protocol Buffers(协议缓冲区) 作为序列化协议。

     引用自微软文档:

    gRPC 的主要优点是:

    • 现代高性能轻量级 RPC 框架。
    • 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
    • 可用于多种语言的工具,以生成强类型服务器和客户端。
    • 支持客户端、服务器和双向流式处理调用。
    • 使用 Protobuf 二进制序列化减少对网络的使用。

    这些优点使 gRPC 适用于:

    • 效率至关重要的轻量级微服务。
    • 需要多种语言用于开发的 Polyglot 系统。
    • 需要处理流式处理请求或响应的点对点实时服务。

     官方支持的gRPC语言,平台和操作系统版本

    LanguageOSCompilers / SDK
    C/C++ Linux, Mac GCC 4.9+, Clang 3.4+
    C/C++ Windows 7+ Visual Studio 2015+
    C# Linux, Mac .NET Core, Mono 4+
    C# Windows 7+ .NET Core, NET 4.5+
    Dart Windows, Linux, Mac Dart 2.2+
    Go Windows, Linux, Mac Go 1.13+
    Java Windows, Linux, Mac JDK 8 recommended (Jelly Bean+ for Android)
    Kotlin/JVM Windows, Linux, Mac Kotlin 1.3+
    Node.js Windows, Linux, Mac Node v8+
    Objective-C macOS 10.10+, iOS 9.0+ Xcode 7.2+
    PHP Linux, Mac PHP 7.0+
    Python Windows, Linux, Mac Python 3.5+
    Ruby Windows, Linux, Mac Ruby 2.3+

    二、ASP.NET 中gRPC应用:

     1、创建gRPC服务项目:新建项目

      2、创建项目代码解析:

      如图可以看到创建目录中:主要添加:greet.proto、GreeterService

      a)greet.proto文件说明:    

    复制代码
    //指定协议缓冲区使用版本
    syntax = "proto3";
    //定义C#实现的命名空间
    option csharp_namespace = "GrpcServiceDemo";
    //定义包名 package greet;
    // 定义gRPC服务 service Greeter { //服务定义方法: rpc SayHello (HelloRequest) returns (HelloReply); } //参数类型定义 // The request message containing the user's name. message HelloRequest { string name = 1; } //相应结果类型定义 // The response message containing the greetings. message HelloReply { string message = 1; }
    复制代码

      b)gRPC服务实现:服务类 GreeterService ,服务类集成的 Greeter.GreeterBase 来自于根据proto文件自动生成的,生成的类在 objDebug etcoreapp3.1目录下    

    复制代码
    //Greeter.GreeterBase由grpc.tools根据proto文件自动生成。
    //文件路径在:objdebug
    etcoreapp3.1
    public class GreeterService : Greeter.GreeterBase
    {
        private readonly ILogger<GreeterService> _logger;
        public GreeterService(ILogger<GreeterService> logger)
        {
            _logger = logger;
        }
        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
    复制代码

      c)Startup文件主要包括:

    复制代码
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            //注入Grpc服务
         services.AddGrpc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { //绑定服务实现接口 endpoints.MapGrpcService<GreeterService>(); //绑定缺省节点输出内容 endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"); }); }); } }
    复制代码

      d)项目文件中添加了:

      <ItemGroup>
        <Protobuf Include="Protosgreet.proto" GrpcServices="Server" />
      </ItemGroup>

      e)配置文件改变:指定以http2协议运行

      "Kestrel": {
        "EndpointDefaults": {
          "Protocols": "Http2"
        }
      }     

      3、创建自己的gRCP服务接口:在创建WebApi项目时默认创建了个天气预报接口,那么就来实现一个获取天气预报的gRPC服务

      a) 添加 weatherforecast.proto 文件,定义服务接口

    复制代码
    syntax = "proto3";
    
    //导入日期类型
    import "google/protobuf/timestamp.proto";
    //导入空类型
    import "google/protobuf/empty.proto";
    
    //命名空间
    option csharp_namespace = "GrpcServiceDemo";
    
    //包名称
    package weather;
    
    //天气服务
    service Weather {
      //指定城市天气
      rpc GetWeather (WeatherReques) returns (WeatherForecastInfo);
    
       //所有城市列表:入参为空
      rpc GetWeatherList (google.protobuf.Empty) returns (WeatherList);
    }
    
    //请求具体城市名称
    message WeatherReques {
      string name = 1;
    }
    
    //返回天气数据列表
    message WeatherList{
      repeated WeatherForecastInfo ListData =1;
    }
    
    //定义返回天气数据类型
    message WeatherForecastInfo {
      //日期时间类型
      google.protobuf.Timestamp Date = 1;
      int32 TemperatureC = 2;
      int32 TemperatureF = 3;
      string Summary = 4;
    }
    复制代码

      b) 实现天气获取接口    

    复制代码
    public class WeatherService : Weather.WeatherBase
    {
        private static readonly string[] Summaries = new[] {"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"};
    
        private readonly ILogger<WeatherService> _logger;
        public WeatherService(ILogger<WeatherService> logger)
        {
            _logger = logger;
        }
    
        public override Task<WeatherForecastInfo> GetWeather(WeatherReques request, ServerCallContext context)
        {
            var rng = new Random();
            var result = new WeatherForecastInfo
            {
                //时间转换
                Date = Timestamp.FromDateTimeOffset(new DateTimeOffset(DateTime.Now.AddDays(1))),
                TemperatureC = rng.Next(-20, 55),
                Summary = $"{Summaries[rng.Next(Summaries.Length)]}"
            };
            return Task.FromResult(result);
        }
    
        public override Task<WeatherList> GetWeatherList(Empty request, ServerCallContext context)
        {
            var rng = new Random();
            var data = Enumerable.Range(1, 5).Select(index => new WeatherForecastInfo
            {
                //时间转换
                Date = Timestamp.FromDateTimeOffset(new DateTimeOffset(DateTime.Now.AddDays(1))),
                TemperatureC = rng.Next(-20, 55),
                Summary = $"{ Summaries[rng.Next(Summaries.Length)]}"
            });
            WeatherList weatherList = new WeatherList();
            weatherList.ListData.Add(data);
            return Task.FromResult(weatherList);
        }
    }
    复制代码

      c)在 Startup终结点路由中注册    

    endpoints.MapGrpcService<WeatherService>();

      d)运行gRPC服务:

        

    三、客户端调用gRPC服务

     1、创建.net core控制台应用;并添加nuget包引用  

    Install-Package Grpc.Net.Client
    Install-Package Google.Protobuf
    Install-Package Grpc.Tools

     2、将服务端中Protos文件,拷贝到客户端中,并在项目文件中添加以下内容,指定Grpc服务类型为:Client

    <ItemGroup>
        <Protobuf Include="Protosgreet.proto" GrpcServices="Client"/>
        <Protobuf Include="Protosweatherforecast.proto" GrpcServices="Client" />
    </ItemGroup>

     3、添加调用Grpc服务代码:

    复制代码
    class Program
    {
        static void Main(string[] args)
        {
            //初始化Grpc通道:参数为gRPC服务地址
            using var channel = GrpcChannel.ForAddress("https://localhost:5001");
            var client = new Greeter.GreeterClient(channel);
            var reply = client.SayHello(
                                new HelloRequest { Name = "GreeterClient" });
    
            Console.WriteLine("Greeting: " + reply.Message);
    
            //调用获取天气列表方法
            Console.WriteLine("调用获取天气列表方法");
            var wsClient = new Weather.WeatherClient(channel);
            var data = wsClient.GetWeatherList(new Empty());
            foreach (var item in data.ListData)
            {
                Console.WriteLine($"天气信息:城市:{item.Summary},时间:{item.Date},温度:{item.TemperatureC},华氏度:{item.TemperatureF}");
            }
            //调用获取天气方法:带参数
            Console.WriteLine("调用获取天气方法:带参数");
            var result = wsClient.GetWeatherAsync(new WeatherRequest { Name = "Warm" }).ResponseAsync.Result;
            Console.WriteLine($"天气信息:城市:{result.Summary},时间:{result.Date},温度:{result.TemperatureC},华氏度:{result.TemperatureF}");
    
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
    复制代码

     4、调用结果如下:

      

     四、总结

      到此已完成gRPC服务的搭建和调用示例,采用gRPC调用服务非常方便,可以直接调用服务方法。

      接下来还会进行更加深入的研究验证。包括调用方式:服务端流式处理、客户端流式处理、双向流式处理等更加深入的用法

    参考:

     官方说明文档:https://grpc.io/docs/what-is-grpc/ 

     微软:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0

     示例源码地址:https://github.com/cwsheng/GrpcDemo

    出处:https://www.cnblogs.com/cwsheng/p/14495453.html

    =======================================================================================

    前言:

     上一篇文章中简单的对gRPC进行了简单了解,并实现了gRPC在ASP.NET Core中服务实现、客户端调用;那么本篇继续对gRPC的4中服务方法定义、其他使用注意点进一步了解学习

    一、gRPC的4类服务方法

    • 简单 RPC(一元方法):客户端向服务器发送单个请求并获得单个响应,就像普通的函数调用一样。

       示例:

    rpc UnaryCall(ExampleRequest) returns (ExampleResponse) {}
    • 服务器端流式 RPC: 客户端发送请求到服务器,拿到一个流去读取返回的消息序列。 客户端读取返回的流,直到里面没有任何消息。通过在 响应 类型前插入 stream 关键字,可以指定一个服务器端的流方法

       示例:

    rpc StreamingFromServer(ExampleRequest) returns (stream ExampleResponse) {}
    • 客户端流式 RPC: 

       示例:

    rpc StreamingFromClient(stream ExampleRequest) returns (ExampleResponse) {}
    • 双向流式 RPC:双方使用读写流去发送一个消息序列。两个流独立操作,因此客户端和服务器可以以任意喜欢的顺序读写:

       比如, 服务器可以在写入响应前等待接收所有的客户端消息,或者可以交替的读取和写入消息,或者其他读写的组合。 每个流中的消息顺序被预留。你可以通过在请求和响应前加 stream 关键字去制定方法的类型。

       示例:

     rpc StreamingBothWays(stream ExampleRequest) returns (stream ExampleResponse) {}

      完整protos如下: 

    复制代码
    syntax = "proto3";
    option csharp_namespace = "GrpcServiceDemo";
    //可添加版本号区分v1/v2 package serviceTypeDemo;
    //服务类型Demo:用于展现gRpc四种服务方法 service ServiceTypeDemo { // Unary:一元方法 rpc UnaryCall (ExampleRequest) returns (ExampleResponse); // Server streaming:服务流 rpc StreamingFromServer (ExampleRequest) returns (stream ExampleResponse); // Client streaming:客户端流 rpc StreamingFromClient (stream ExampleRequest) returns (ExampleResponse); // Bi-directional streaming:双向流 rpc StreamingBothWays (stream ExampleRequest) returns (stream ExampleResponse); } //请求对象 message ExampleRequest { int32 pageIndex = 1; int32 pageSize = 2; bool isDescending = 3; } //响应对象 message ExampleResponse{ object result = 1; int32 total = 2; }
    复制代码

      服务实现:实现相对简单,主要展示读取流和写入流  

    复制代码
    public class ServerTypeService : ServiceTypeDemo.ServiceTypeDemoBase
    {
        public override Task<ExampleResponse> UnaryCall(ExampleRequest request, ServerCallContext context)
        {
            ExampleResponse resp = GetResp();
            return Task.FromResult(resp);
        }
        private static ExampleResponse GetResp()
        {
            var resp = new ExampleResponse();
            resp.Total = new Random().Next(1, 20);
            resp.Result.Add("abc");
            resp.Result.Add("efg");
            return resp;
        }
        public async override Task StreamingFromServer(ExampleRequest request, IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
        {
            var responses = new List<ExampleResponse>();
            responses.Add(GetResp());
            responses.Add(GetResp());
            responses.Add(GetResp());
            foreach (var response in responses)
            {
                //写入流中
                await responseStream.WriteAsync(response);
            }
        }
        public async override Task<ExampleResponse> StreamingFromClient(IAsyncStreamReader<ExampleRequest> requestStream, ServerCallContext context)
        {
            int pointCount = 0;
            //读取传入流
            while (await requestStream.MoveNext())
            {
                var point = requestStream.Current;
                pointCount++;
            }
            var info = GetResp();
            info.Total = pointCount;
            return info;
        }
        public async override Task StreamingBothWays(IAsyncStreamReader<ExampleRequest> requestStream, IServerStreamWriter<ExampleResponse> responseStream, ServerCallContext context)
        {
            //读取内容
            while (await requestStream.MoveNext())
            {
                var note = requestStream.Current;
                var responses = new List<ExampleResponse>();
                responses.Add(GetResp());
                responses.Add(GetResp());
                //循环写入
                foreach (var prevNote in responses){
                    await responseStream.WriteAsync(prevNote);
                }
            }
        }
    }
    复制代码

    二、gRPC其他注意点  

     1、截止时间和取消处理

        截止时间功能让 gRPC 客户端可以指定等待调用完成的时间。 超过截止时间时,将取消调用。

       截止时间配置:

    • 在进行调用时,使用 CallOptions.Deadline 配置截止时间。
    • 没有截止时间默认值。 gRPC 调用没有时间限制,除非指定了截止时间。
    • 截止时间指的是超过截止时间的 UTC 时间。 例如,DateTime.UtcNow.AddSeconds(5) 是从现在起 5 秒的截止时间。
    • 如果使用的是过去或当前的时间,则调用将立即超过截止时间。
    • 截止时间随 gRPC 调用发送到服务,并由客户端和服务独立跟踪。 gRPC 调用可能在一台计算机上完成,但当响应返回给客户端时,已超过了截止时间。

        如果超过了截止时间,客户端和服务将有不同的行为:

    • 客户端将立即中止基础的 HTTP 请求并引发 DeadlineExceeded 错误。 客户端应用可以选择捕获错误并向用户显示超时消息。
    • 在服务器上,将中止正在执行的 HTTP 请求,并引发 ServerCallContext.CancellationToken。 尽管中止了 HTTP 请求,gRPC 调用仍将继续在服务器上运行,直到方法完成。 将取消令牌传递给异步方法,使其随调用一同被取消,这非常重要。例如,向异步数据库查询和 HTTP 请求传递取消令牌。 传递取消令牌让取消的调用可以在服务器上快速完成,并为其他调用释放资源。

       使用方式如下:

    复制代码
    var defaultMethodConfig = new MethodConfig
    {
        Names = { MethodName.Default },
        RetryPolicy = new RetryPolicy
        {
            //最大重试5次
            MaxAttempts = 5,
            //重试尝试之间的初始退避延迟。
            InitialBackoff = TimeSpan.FromSeconds(1),
            //最大退避会限制指数退避增长的上限。
            MaxBackoff = TimeSpan.FromSeconds(5),
            //每次重试尝试后,退避将乘以该值,并将在乘数大于 1 的情况下以指数方式增加。
            BackoffMultiplier = 1.5,
            //状态代码的集合,在此集合中重试
            RetryableStatusCodes = { StatusCode.Unavailable }
        }
    };
    //初始化Grpc通道:参数为gRPC服务地址
    using var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions()
    {
        ThrowOperationCanceledOnCancellation = true,
        //设置重试:v2.36版本添加
        ServiceConfig = new ServiceConfig() { MethodConfigs = { defaultMethodConfig } }
    });
    
    string token = string.Empty;
    var client = new Greeter.GreeterClient(channel);
    //设置超时5秒;headers:可传递头信息:如认证串
    Metadata metadata = new Metadata();
    metadata.Add("Authorization", $"Bearer {token}");
    var reply = client.SayHello(new HelloRequest { Name = "GreeterClient" },
        headers: metadata,
        deadline: DateTime.UtcNow.AddSeconds(5));
    复制代码

     2、gRPC-Web应用

       gRPC-Web 允许浏览器 JavaScript 和 Blazor 应用调用 gRPC 服务。 无法从基于浏览器的应用中调用 HTTP/2 gRPC 服务。 可将托管于 ASP.NET Core 中的 gRPC 服务配置为随 HTTP/2 gRPC 一起支持 gRPC-Web。

      有两种方式可将 gRPC-Web 添加到 ASP.NET Core 应用中:

    • 在 ASP.NET Core 中同时支持 gRPC-Web 和 gRPC HTTP/2。 此选项会使用 Grpc.AspNetCore.Web 包提供的中间件。
    • 使用 Envoy 代理的 gRPC-Web 支持将 gRPC-Web 转换为 gRPC HTTP/2。 转换后的调用随后会转发给 ASP.NET Core 应用。

      a)添加Grpc.AspNetCore.Web 包引用

      b)修改Startup.cs文件如下:

    复制代码
    public void ConfigureServices(IServiceCollection services){
        services.AddGrpc();
    }
    public void Configure(IApplicationBuilder app){
        app.UseRouting();
        app.UseGrpcWeb();//启用gRPCWeb
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb();
        });
    }
    复制代码

        c)Cors跨域设置:

    复制代码
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddGrpc();
        services.AddCors(o => o.AddPolicy("AllowAll", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader()
                   .WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
        }));
    }
    public void Configure(IApplicationBuilder app)
    {
        app.UseRouting();
        app.UseGrpcWeb();
        app.UseCors();
        app.UseEndpoints(endpoints =>{
            endpoints.MapGrpcService<GreeterService>().EnableGrpcWeb()
                                                      .RequireCors("AllowAll");
        });
    } 
    复制代码

     3、gRPC进程间调用:需要.NET 5;

      服务端设置:   

    复制代码
    public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
    
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(options =>
                {
                    if (File.Exists(SocketPath))
                    {
                        File.Delete(SocketPath);
                    }
                    options.ListenUnixSocket(SocketPath);
                });
            });
    复制代码

      客户端设置:  

    复制代码
    public class UnixDomainSocketConnectionFactory
    {
        private readonly EndPoint _endPoint;
    
        public UnixDomainSocketConnectionFactory(EndPoint endPoint)
        {
            _endPoint = endPoint;
        }
    
        public async ValueTask<Stream> ConnectAsync(SocketsHttpConnectionContext _,
            CancellationToken cancellationToken = default)
        {
            var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
    
            try
            {
                await socket.ConnectAsync(_endPoint, cancellationToken).ConfigureAwait(false);
                return new NetworkStream(socket, true);
            }
            catch
            {
                socket.Dispose();
                throw;
            }
        }
    }
    复制代码

        在创建通道连接时:

    复制代码
    public static readonly string SocketPath = Path.Combine(Path.GetTempPath(), "socket.tmp");
    
    public static GrpcChannel CreateChannel()
    {
        var udsEndPoint = new UnixDomainSocketEndPoint(SocketPath);
        var connectionFactory = new UnixDomainSocketConnectionFactory(udsEndPoint);
        var socketsHttpHandler = new SocketsHttpHandler
        {
            ConnectCallback = connectionFactory.ConnectAsync
        };
    
        return GrpcChannel.ForAddress("http://localhost", new GrpcChannelOptions
        {
            HttpHandler = socketsHttpHandler
        });
    }
    复制代码

     4、相关配置项:

      服务端:

      gRPC 服务在 Startup.cs 中使用 AddGrpc 进行配置。

    选项默认值描述
    MaxSendMessageSize null 可以从服务器发送的最大消息大小(以字节为单位)。 尝试发送超过配置的最大消息大小的消息会导致异常。 设置为 null时,消息的大小不受限制。
    MaxReceiveMessageSize 4 MB 可以由服务器接收的最大消息大小(以字节为单位)。 如果服务器收到的消息超过此限制,则会引发异常。 增大此值可使服务器接收更大的消息,但可能会对内存消耗产生负面影响。 设置为 null时,消息的大小不受限制。
    EnableDetailedErrors false 如果为 true,则当服务方法中引发异常时,会将详细异常消息返回到客户端。 默认值为 false 将 EnableDetailedErrors 设置为 true 可能会泄漏敏感信息。
    CompressionProviders gzip 用于压缩和解压缩消息的压缩提供程序的集合。 可以创建自定义压缩提供程序并将其添加到集合中。 默认已配置提供程序支持 gzip 压缩。
    ResponseCompressionAlgorithm null 压缩算法用于压缩从服务器发送的消息。 该算法必须与 CompressionProviders 中的压缩提供程序匹配。 若要使算法可压缩响应,客户端必须通过在 grpc-accept-encoding 标头中进行发送来指示它支持算法。
    ResponseCompressionLevel null 用于压缩从服务器发送的消息的压缩级别。
    Interceptors None 随每个 gRPC 调用一起运行的侦听器的集合。 侦听器按注册顺序运行。 全局配置的侦听器在为单个服务配置的侦听器之前运行。 有关 gRPC 侦听器的详细信息,请参阅 gRPC 侦听器与中间件
    IgnoreUnknownServices false 如果为 true,则对未知服务和方法的调用不会返回 UNIMPLEMENTED 状态,并且请求会传递到 ASP.NET Core 中的下一个注册中间件。

      客户端:

       gRPC 客户端配置在 GrpcChannelOptions 中进行设置。 下表描述了用于配置 gRPC 通道的选项      

    选项默认值描述
    HttpHandler 新实例 用于进行 gRPC 调用的 HttpMessageHandler 可以将客户端设置为配置自定义 HttpClientHandler,或将附加处理程序添加到 gRPC 调用的 HTTP 管道。 如果未指定 HttpMessageHandler,则会通过自动处置为通道创建新 HttpClientHandler 实例。
    HttpClient null 用于进行 gRPC 调用的 HttpClient 此设置是 HttpHandler 的替代项。
    DisposeHttpClient false 如果设置为 true 且指定了 HttpMessageHandler 或 HttpClient,则在处置 GrpcChannel 时,将分别处置 HttpHandler 或 HttpClient
    LoggerFactory null 客户端用于记录有关 gRPC 调用的信息的 LoggerFactory 可以通过依赖项注入来解析或使用 LoggerFactory.Create 来创建 LoggerFactory 实例。 有关配置日志记录的示例,请参阅 .NET 上 gRPC 中的日志记录和诊断
    MaxSendMessageSize null 可以从客户端发送的最大消息大小(以字节为单位)。 尝试发送超过配置的最大消息大小的消息会导致异常。 设置为 null时,消息的大小不受限制。
    MaxReceiveMessageSize 4 MB 可以由客户端接收的最大消息大小(以字节为单位)。 如果客户端收到的消息超过此限制,则会引发异常。 增大此值可使客户端接收更大的消息,但可能会对内存消耗产生负面影响。 设置为 null时,消息的大小不受限制。
    Credentials null 一个 ChannelCredentials 实例。 凭据用于将身份验证元数据添加到 gRPC 调用。
    CompressionProviders gzip 用于压缩和解压缩消息的压缩提供程序的集合。 可以创建自定义压缩提供程序并将其添加到集合中。 默认已配置提供程序支持 gzip 压缩。
    ThrowOperationCanceledOnCancellation false 如果设置为 true,则在取消调用或超过其截止时间时,客户端将引发 OperationCanceledException
    MaxRetryAttempts 5 最大重试次数。 该值限制服务配置中指定的任何重试和 hedging 尝试值。单独设置该值不会启用重试。 重试在服务配置中启用,可以使用 ServiceConfig 来启用。 null 值会删除最大重试次数限制。 有关重试的更多详细信息,请参阅“暂时性故障处理与 gRPC 重试”。
    MaxRetryBufferSize 16 MB 在重试或 hedging 调用时,可用于存储发送的消息的最大缓冲区大小(以字节为单位)。 如果超出了缓冲区限制,则不会再进行重试,并且仅保留一个 hedging 调用,其他 hedging 调用将会取消。 此限制将应用于通过通道进行的所有调用。 值 null 移除最大重试缓冲区大小限制。
    MaxRetryBufferPerCallSize 1 MB 在重试或 hedging 调用时,可用于存储发送的消息的最大缓冲区大小(以字节为单位)。 如果超出了缓冲区限制,则不会再进行重试,并且仅保留一个 hedging 调用,其他 hedging 调用将会取消。 此限制将应用于一个调用。 值 null 移除每个调用的最大重试缓冲区大小限制。
    ServiceConfig null gRPC 通道的服务配置。 服务配置可以用于配置 gRPC 重试

    参考:

     官方说明文档:https://grpc.io/docs/what-is-grpc/ 

     微软:https://docs.microsoft.com/zh-cn/aspnet/core/grpc/?view=aspnetcore-3.0

     示例源码地址:https://github.com/cwsheng/GrpcDemo

      

    出处:https://www.cnblogs.com/cwsheng/p/14588078.html

    您的资助是我最大的动力!
    金额随意,欢迎来赏!
    款后有任何问题请给我留言。

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我。(●'◡'●)

    如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,求打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【Jack_孟】!

  • 相关阅读:
    ILockBytes Windows Mobile 6.5
    C# 中 in,out,ref 的作用与区别
    riched32.dll riched20.dll msftedit.dll 解析
    C# 解决窗体假死的状态
    testform
    ParallelProgramming-多消费者,多生产者同时运行并行
    C# 多线程控制 通讯
    C# 多线程
    iSpy免费的开源视频监控平台
    核心J2EE模式
  • 原文地址:https://www.cnblogs.com/mq0036/p/14646530.html
Copyright © 2011-2022 走看看