gRPC在 ASP.NET Core 中应用学习
一、gRPC简介:
gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。 gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建。它使用HTTP/2作为通信协议,使用 Protocol Buffers(协议缓冲区) 作为序列化协议。
引用自微软文档:
gRPC 的主要优点是:
- 现代高性能轻量级 RPC 框架。
- 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。
- 可用于多种语言的工具,以生成强类型服务器和客户端。
- 支持客户端、服务器和双向流式处理调用。
- 使用 Protobuf 二进制序列化减少对网络的使用。
这些优点使 gRPC 适用于:
- 效率至关重要的轻量级微服务。
- 需要多种语言用于开发的 Polyglot 系统。
- 需要处理流式处理请求或响应的点对点实时服务。
官方支持的gRPC语言,平台和操作系统版本
Language | OS | Compilers / 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文件自动生成的,生成的类在 obj\Debug\netcoreapp3.1
目录下
//Greeter.GreeterBase由grpc.tools根据proto文件自动生成。 //文件路径在:obj\debug\netcoreapp3.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="Protos\greet.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="Protos\greet.proto" GrpcServices="Client"/> <Protobuf Include="Protos\weatherforecast.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
关注我】。(●'◡'●)
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【因为,我的写作热情也离不开您的肯定与支持,感谢您的阅读,我是【Jack_孟】!
本文来自博客园,作者:jack_Meng,转载请注明原文链接:https://www.cnblogs.com/mq0036/p/14646530.html
【免责声明】本文来自源于网络,如涉及版权或侵权问题,请及时联系我们,我们将第一时间删除或更改!