ディレクトリ
- gRPCを使用してASP.NETコア3.0
- ASP.NETコア3.0 gRPC双方向の流れ
- ASP.NETコア3.0 gRPC認証と承認
I.はじめに
前の記事「ASP.NET 3.0のコア使用gRPCは」の機能がgRPCで、双方向のフロー制御サポートのgRPCはのための非常に強いです、リアルタイムのプッシュメッセージングをサポートし、通話のgRPCサポート双方向の流れの中で言及されました。
II。gRPCストリームは何ですか
シンプルなRPC(単項RPC)、ストリーミングサーバのRPC(サーバーストリーミングRPC)、クライアントストリーミングRPC(クライアントストリーミングRPC)、双方向ストリーミングRPC(双方向ストリーミングRPC):gRPC、すなわち、サービス、の4種類があります。 。彼らは主に次のような特徴があります:
サービスの種類 | 機能 |
---|---|
シンプルなRPC | 一般的なRPC呼び出し、リクエストオブジェクトを渡し、戻りオブジェクトを返します。 |
RPCサーバーストリーミング | 要求オブジェクトを渡し、サーバは、結果の複数のオブジェクトを返すことができます |
ストリーミングクライアントRPC | 複数の着信クライアントがオブジェクトを要求し、サーバは、結果オブジェクトを返します。 |
双方向フローRPC | ストリーミングクライアントとサーバーのRPCのRPCの流れをバインド、あなたは結果オブジェクトが複数返され、リクエストオブジェクトを複数渡すことができます |
III。なぜgRPCサポートストリーミング
gRPC通信は、HTTP / 2ストリームへの双方向の流れを達成するために、HTTP / 2に基づいています。多重化HTTP / 2であるために、ストリームの流れの概念を持つHTTP / 2。ビジネス;双方向シリアルストリームは、HTTP / 2接続を介してデータフレームを交換するための独立したサーバやクライアントであり、それはより完全な対話処理論理ユニット、完全なリソース要求、応答データ交換処理のすなわち表現として見ることができます処理は、ストリーム内で完結処理のために生活のストリーム終わりを意味しています。
次のような機能は次のとおりです。
- HTTP / 2接続は同時にいずれかのエンドポイントスイッチフレーム、オープンフローの複数を保持することができます
- ストリームは、単独で、または共有のクライアントまたはサーバの作成と使用を使用することができます
- ストリームは、どちらかの端で閉鎖することができます
- データストリーム順に送受信されます
- ストリーム識別子は自然数を表し、1 ^ 31-1間隔2に、端末は、流量分布を作成しなければなりません
- 流れの間に論理的に並行して、の存在とは無関係
撮影したHTTP / 2マルチプレクサと彼の同類ノートニエヨンジュンによって
四.gRPCは、通話の双方向のフローを使用します
私たちは、その後、ストリーミングサーバ、単純です我々はRPCとRPCの簡単な双方向の流れを持っている場合、第二のセクションに記載されているサービスの4種類に応じて、コールフロー、双方向の流れについて次の直接話が含まれていない前述のRPCのRPCで書きますRPCとRPCクライアントの流れが自然に問題ありません。
ここでは、引き続き使用する以前のコードを、目標は、複数の猫に一度お風呂を達成すべきです。
①まず、でLuCat.proto
、猫のためのカウント統計を数2 RPCを定義し、双方向の流れRPC BathTheCatは猫を入浴するために使用しました
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;
}
②実装サービスを追加
ここではReSharperの下アムウェイ、非常に便利
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方法は、クライアントから送信されたCATIDを複数受信し、キューに追加、などは、クライアント順次浴から送信され、クライアントに返されました。
③クライアントの実装
同上猫ランダムサーバーへの送信10、および、結果バス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("洗澡完毕");
④実行
あなたは、コールの双方向の流れが成功すると、クライアントは、バスリクエストオブジェクト10猫を送信し、サーバは風呂結果オブジェクト10猫を返す見ることができます。そして、通話gRPCの双方向のフローであるリアルタイムのプッシュ、です。
ここでは、ストリーミングクライアントまたはサーバ側のストリーミングコールに進化するために自分自身を向上させることができます。次に、クライアントは、サーバがサーバ呼び出しをストリーミングしている各猫の結果バスを返し、猫IDリストを送信します。順番に、クライアントは、サーバはすべての猫のための入浴時間の結果を返します(猫のすべてのビジネスとして見られるように入浴することは、ビジネスの結果を返します)、猫IDを送信する、クライアントの呼び出しをストリーミングしています。ここで私は発揮しません。
V.フロー制御
gRPCストリーミングのサポートはアクティブ解除の流れを制御するために呼び出すので、フロー制御タイムアウト制限を導出することができます。
我々は対流制御を解除するために使用したものであるCancellationTokenパラメータを渡すことができますストリーミングコール:
私たちは、コードの第四項にあるものを変換:
①クライアント
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.");
}
});
②サーバー
//遍历队列开始洗澡
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);//此处主要是为了方便客户端能看出流调用的效果
}
③実行
双方向のフロー・コール2.5S後に設定した結果を返すコールの最終結果を確認するために、顧客からのトラフィックを削除し、10猫の入浴のすべてを受け取っていない、ストリームが、これは制御gRPCの流れで、キャンセルされました。
VI。終了
ここでは、リアルタイムのプッシュ、サービス・クライアントまたはクライアントからサーバへリアルタイム短プッシュメッセージが、伝統的な意味をプッシュする接続と長いイニシアチブをストリーミング呼び出すことができ、ブロードキャストメッセージは、あなたがサーバー側のストリーミングであるかどうか、同じではありませんクライアント・フローまたは双方向の流れは、クライアントの要求により通信のフローを確立するために、クライアントによって開始されなければなりません。
VII。参考文献
タイプGRPCの4つのサービス twtydgoによって
HTTP / 2マルチプレクサと彼の同類ノートニエヨンジュンによって