NET Core3 high performance RPC framework NET Core 3.0 using gRPC ASP.NET Core 3.0 using gRPC not compile problem

NET Core 3.0 using gRPC

I. Introduction

Previous article " ASP.NET 3.0 Core use gRPC " was mentioned in gRPC support two-way flow of calls, support real-time push messaging, a feature of which is the gRPC, and gRPC on the bi-directional flow control support is very strong for.

II. What is gRPC stream

gRPC There are four types of services, namely: simple RPC (Unary RPC), a streaming server RPC (Server streaming RPC), the client streaming RPC (Client streaming RPC), two-way streaming RPC (Bi-directional streaming RPC) . They are mainly has the following characteristics:

Service type Feature
Simple RPC General rpc call, passing a request object and returns a return object
RPC server streaming Passing a request object, the server may return a plurality of result objects
Streaming client RPC Multiple incoming client requests an object, the server returns a result object
Two-way flow RPC Binding streaming client and server RPC RPC flow, you can pass a plurality of request object, the plurality of result objects returned

III. Why gRPC support streaming

gRPC communication is based on HTTP / 2 to achieve its bidirectional streams to HTTP / 2 stream. HTTP / 2 with the concept of stream flow in order to be multiplexed HTTP / 2 in. Bidirectional serial stream is an independent server and client for exchanging data frames over HTTP / 2 connections, it can be seen as a more complete interaction processing logic unit, i.e. the expression of a complete resource request, response data exchange process; a business processing means for processing completed within a stream, the stream end of life.

Features are as follows:

  • A HTTP / 2 connections can simultaneously hold a plurality of open flow, either end-point switch frame
  • Stream may be used alone or creation and use of shared client or server
  • Stream may be closed at either end
  • In the data stream to be transmitted and received in the order
  • Stream identifier indicates a natural number, 1 to 2 ^ 31-1 interval, the terminal has to create flow distribution
  • Between the flow stream and logically in parallel, independent of the presence of

Taken  HTTP / 2 multiplexers and his ilk notes  by Nie Yong

Four .gRPC use two-way flow of calls

We write in the foregoing RPC RPC are simple, does not include call flow, the following direct talk about the two-way flow, according to four types of service listed in the second section, if we have a simple two-way flow of RPC and RPC, then the streaming server RPC and RPC client flow naturally there will be no problem.

Here we continue to use the earlier code , the goal is to be achieved once to multiple cat a bath.

① First, in  LuCat.proto defining the number two rpc, a Count statistics for cats, a two-way flow RPC BathTheCat used to bathe a cat

syntax = "proto3";

option csharp_namespace = "AspNetCoregRpcService";

import "google/protobuf/empty.proto";
package LuCat; //定义包名 //定义服务 service LuCat{ //定义给猫洗澡双向流rpc rpc BathTheCat(stream BathTheCatReq) returns ( stream BathTheCatResp); //定义统计猫数量简单rpc rpc Count(google.protobuf.Empty) returns (CountCatResult); } message SuckingCatResult{ string message=1; } message BathTheCatReq{ int32 id=1; } message BathTheCatResp{ string message=1; } message CountCatResult{ int32 Count=1; }

② add the implementation services

Here Amway under Resharper, very convenient

private readonly ILogger<LuCatService> _logger;
private static readonly List<string> Cats=new List<string>(){"英短银渐层","英短金渐层","美短","蓝猫","狸花猫","橘猫"}; private static readonly Random Rand=new Random(DateTime.Now.Millisecond); public LuCatService(ILogger<LuCatService> logger) { _logger = logger; } public override async Task BathTheCat(IAsyncStreamReader<BathTheCatReq> requestStream, IServerStreamWriter<BathTheCatResp> responseStream, ServerCallContext context) { var bathQueue=new Queue<int>(); while (await requestStream.MoveNext()) { //将要洗澡的猫加入队列 bathQueue.Enqueue(requestStream.Current.Id); _logger.LogInformation($"Cat {requestStream.Current.Id} Enqueue."); } //遍历队列开始洗澡 while (bathQueue.TryDequeue(out var catId)) { await responseStream.WriteAsync(new BathTheCatResp() { Message = $"铲屎的成功给一只{Cats[catId]}洗了澡!" }); await Task.Delay(500);//此处主要是为了方便客户端能看出流调用的效果 } } public override Task<CountCatResult> Count(Empty request, ServerCallContext context) { return Task.FromResult(new CountCatResult() { Count = Cats.Count }); }

BathTheCat method receives a plurality of catid sent by the client, and then add them to the queue, and the like has been transmitted from the client sequentially bath and returned to the client.

③ client implementation

Id cat random transmission 10 to the server, and then receives results bath 10.

var channel = GrpcChannel.ForAddress("https://localhost:5001");
var catClient = new LuCat.LuCatClient(channel);
//获取猫总数 var catCount = await catClient.CountAsync(new Empty()); Console.WriteLine($"一共{catCount.Count}只猫。"); var rand = new Random(DateTime.Now.Millisecond); var bathCat = catClient.BathTheCat(); //定义接收吸猫响应逻辑 var bathCatRespTask = Task.Run(async() => { await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()) { Console.WriteLine(resp.Message); } }); //随机给10个猫洗澡 for (int i = 0; i < 10; i++) { await bathCat.RequestStream.WriteAsync(new BathTheCatReq() {Id = rand.Next(0, catCount.Count)}); } //发送完毕 await bathCat.RequestStream.CompleteAsync(); Console.WriteLine("客户端已发送完10个需要洗澡的猫id"); Console.WriteLine("接收洗澡结果:"); //开始接收响应 await bathCatRespTask; Console.WriteLine("洗澡完毕");

④ run

You can see the two-way flow of the call is successful, the client sends a request object 10 cat a bath, the server returns a result object 10 cat a bath. And is a real-time push, which is a two-way flow of calls gRPC.

Here you can improve yourself to evolve into a streaming client or server-side streaming call. The client sends a cat Id list, then the server returns the results of each cat a bath, which is streaming server calls. The client in turn sends cat Id, then the server returns a bath-time results for all cats (cat a bath all to be seen as a business, returns the result of business), is streaming client calls. Here I will not demonstrate.

V. Flow Control

gRPC streaming support calls to control the flow of active cancellation, and thus may be derived flow control timeout restrictions.

Streaming calls that can pass a CancellationToken parameter, which is what we used to cancel convection control:

1569467990882

Transform what we are in the fourth section of the code:

① Client

var cts = new CancellationTokenSource();
//指定在2.5s后进行取消操作
cts.CancelAfter(TimeSpan.FromSeconds(2.5));
var bathCat = catClient.BathTheCat(cancellationToken: cts.Token); //定义接收吸猫响应逻辑 var bathCatRespTask = Task.Run(async() => { try { await foreach (var resp in bathCat.ResponseStream.ReadAllAsync()) { Console.WriteLine(resp.Message); } } catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled) { Console.WriteLine("Stream cancelled."); } });

② server

//遍历队列开始洗澡
while (!context.CancellationToken.IsCancellationRequested && bathQueue.TryDequeue(out var catId))
{
    _logger.LogInformation($"Cat {catId} Dequeue."); await responseStream.WriteAsync(new BathTheCatResp() { Message = $"铲屎的成功给一只{Cats[catId]}洗了澡!" }); await Task.Delay(500);//此处主要是为了方便客户端能看出流调用的效果 }

③ run

Set up after the two-way flow call 2.5s remove traffic from the customer to see the end result of the call, and did not receive all of the 10 cat bathing return a result, the stream has been canceled, this is the flow of control gRPC.

VI. End

Here you can call streaming real-time push, service-to-client or client-to-server real-time short push messages, but the connection and long initiative to push the traditional sense, a broadcast message is not the same, whether you are a server-side streaming, the client-flow or two-way flow, must be initiated by the client to establish a flow of communication by client requests.

VII. References

ASP.NET Core 3.0 using gRPC not compile problem

Guess you like

Origin www.cnblogs.com/Leo_wl/p/11593681.html