gRPCを使用する.NET Core 3.0双方向メッセージストリーム

6874 ワード

目次
紹介する
ソフトウェアの説明
サーバインフラストラクチャ(GrpcServer Helper)
顧客インフラストラクチャ(GrpcClientHelper)
GrpcServerとGrpcClient
実行例
結論
  • ダウンロードソース-29.8 KB
  • 紹介する


    .NET Core 3.0の最も重要な新機能の1つ(現在発表されており、今年後半に発表される予定)は、gRPCメッセージングのサポートです.Wikipediaの説明gRPCは以下の通りです.
    gRPC(gRPCリモートプロシージャ呼び出し)は、Googleで最初に開発されたオープンソースリモートプロシージャ呼び出し(RPC)システムである.HTTP/2を使用して転送され、Protocol Buffersをインタフェース記述言語として使用し、認証、双方向ストリームとストリーム制御、ブロックまたは非ブロックバインド、キャンセルとタイムアウトなどの機能を提供します.多くの言語に対して、プラットフォーム間でクライアントとサーバのバインドを生成します.最も一般的な使用シーンには、マイクロサービスアーキテクチャに接続されたサービスと、モバイルデバイス、ブラウザクライアントをバックエンドサービスに接続するサービスが含まれます.
    gRPCの「キラー級機能」は、同期フルデュプレクスストリームのサポートだそうです.HTTP/2プロトコルは、トランスポートプロトコルとして使用される.プロトコルバッファは、有効なシーケンス化に使用されます.
    上述ように、NET Core 3.0フレームワークは、gRPCベースの通信をサポートします.Visual Studio 2019は、gRPCサービスのテンプレートコードを提供している.ただし、このコードは、メッセージ・ストリームのない一方向通信のみを提供します.このプロジェクトは現在の仕事の出発点です.私のコードでは、サーバとクライアントの共通コードを選択し、gRPCの使用をサポートしています.NET Core 3.0双方向メッセージ・ストリームの便利なインフラストラクチャを組み合わせます.

    ソフトウェアの説明


    インフラストラクチャプロジェクト(DLL)GrpcServer HelperとGrpcClientHelperはHelpersフォルダに配置されます.これらは、特定のサーバとクライアントによってそれぞれ参照および使用できます.クライアントとサーバとの間でフルデュプレクスgRPCメッセージ交換を行うと仮定して,補助DLLを開発した.ただし、メッセージ構造や処理には制限はありません.これらの機能は、特定のサーバとクライアントに依存します.
    gRPCデータと特定のサーバとクライアントで共有するprotoファイルcommunicationを処理する.protoで定義します.このファイルは、クライアントからサーバ、およびサーバからクライアントへのメッセージに対して、適切なenumおよびメッセージ交換を開始するCreateStreaming()関数の異なるタイプを提供します.Visual Studio 2019はprotoファイルからC#クラスを生成する.

    サーバインフラストラクチャ(GrpcServer Helper)


    クラスGeneralGrpcServiceは、サーバ側の双方向ストリームにインフラストラクチャを提供します.このクラスは,要求メッセージタイプTRequest,TResponseとそれぞれパラメータ化される.その方法CreateDuplexStreaming()は、サブスクライバ管理、要求メッセージ処理、応答メッセージ生成、クライアントへの送信などの主要なルーチンプログラムを処理する.
    public async Task CreateDuplexStreaming(
    	IAsyncStreamReader requestStream,
    	IServerStreamWriter responseStream,
    	ServerCallContext context)
    {
        var httpContext = context.GetHttpContext();
        Logger.LogInformation($"Connection id: {httpContext.Connection.Id}");
    
        if (!await requestStream.MoveNext())
            return;
    
        var clientId = _messageProcessor.GetClientId(requestStream.Current);
        Logger.LogInformation($"{clientId} connected");
        var subscriber = new SubscribersModel
        {
            Subscriber = responseStream,
            Id = $"{clientId}"
        };
    
        _serverGrpcSubscribers.AddSubscriber(subscriber);
    
        do
        {
            if (requestStream.Current == null)
                continue;
    
            var resultMessage = _messageProcessor.Process(requestStream.Current);
            if (resultMessage == null)
                continue;
    
            await _serverGrpcSubscribers.BroadcastMessageAsync(resultMessage);
        } while (await requestStream.MoveNext());
    
        _serverGrpcSubscribers.RemoveSubscriber(subscriber);
        Logger.LogInformation($"{clientId} disconnected");
    }

    クラスサーバGrpcSubscribersBaseはサブスクライバ(クライアント)を管理し、abstract class MessageProcessorBaseは、要求メッセージを処理し、応答を生成するためのabstractメソッドabstract TResponse Process(TRequest message)を開示する.柔軟性のために,これらの方法の具体的な実装が可能な異常(もしあれば)を処理できると仮定した.最後に、class SubscribersModelは、応答メッセージをクライアントに送信するためのサブスクライバモデルを提供する.

    顧客インフラストラクチャ(GrpcClientHelper)


    abstract class GrpcClientBaseが提供するDo()メソッドのみが、クライアントからのメッセージ・ストリームを確保することです.
    public async Task Do(
    	Channel channel, 
    	Action onConnection = null, 
    	Action onShuttingDown = null)
    {
        using (var duplex = CreateDuplexClient(channel))
        {
            onConnection?.Invoke();
    
            var responseTask = Task.Run(async () =>
            {
                while (await duplex.ResponseStream.MoveNext(CancellationToken.None))
                Console.WriteLine($"{duplex.ResponseStream.Current}");
            });
    
            string payload;
            while (!string.IsNullOrEmpty(payload = MessagePayload))
            await duplex.RequestStream.WriteAsync(CreateMessage(payload));
    
            await duplex.RequestStream.CompleteAsync();
        }
    
        onShuttingDown?.Invoke();
        await channel.ShutdownAsync();
    }

    GrpcServerとGrpcClient


    具体的なサーバGrpcServerはVisual Studio 2019によって作成され、ASP.MVC Coreテンプレートは、gRPCプロジェクトとして使用されます.これにより、class MessageProcessor:MessageProcessorBaseおよびclass Server GrpcSubscribers:Server GrpcSubscribersBaseが適切なルートクラスGrpcServer Helperを拡張します.クラスMessageProcessorは、クライアント要求メッセージの必須処理を提供し、必要に応じて応答メッセージを送信します.クラス・サーバGrpcSubscribersは、サブスクライバ管理を調整します(特定のケースでは、祖先と何の違いもなく、説明の目的でのみ使用されます).クラス・サーバGrpcSubscribersとMessageProcessorは、Startupクラスにsingletonとして追加するメソッドConfigureServices(IServiceCollection services)のサービス・セットにあります.
    services.AddSingleton();
    services.AddSingleton();

    拡張生成Messaging.MessagingBaseタイプのサービスクラスDuplexServiceはメソッドStartupにマッピングする必要があります.Configure()の端点は、次のようになります.
    app.UseEndpoints(endpoints =>
    {
        // ...
        endpoints.MapGrpcService();
    });

    サーバとクライアントは、暗号化メッセージ(HTTPS)の交換をサポートします.このため、サーバは、そのKestrel構成においてgrpcServerを使用する.pfxファイル.クライアントと証明書ファイルcertificateを使用します.crt.どちらのファイルも、ここに記載されているマニュアルに従ってインストールされたOpenSSLアプリケーションによって作成されます.
    Proto Bufferを使用するシーケンス化のため、サーバとクライアントは同じprotoファイルcommunicationを共有する.proto.このファイルは、ストリーミング・メッセージ・サービスを定義します.
    service Messaging
    {
        rpc CreateStreaming (stream RequestMessage) returns (stream ResponseMessage);
    }

    リクエストおよびレスポンスメッセージフォーマット、および適切な列挙器.
    Visual Studioでprotoファイルをサーバとクライアントプロジェクトに含めて、適切なC#コードが生成されることを確認する方法を見つけることができませんでした.だから私はGrpcServerにいます.csprojとGrpcClient.csprojプロジェクトファイルでこの操作を手動で実行します.これらのファイルには、マークされたコメントセクションを追加しました.

    実行例


    この例を実行するには、ソリューション全体を構築します(protoファイルからクラスを生成することもあります).そして...GrpcServerの実行
    dotnet GrpcServer.dll

    ......コマンドとその完全な起動後、1つ以上の実行を続行します.
    dotnet GrpcClient.dll

    ...で行ないます.
    クライアントコンソールに、Enterで終わるメッセージを入力します.サーバは、メッセージを受信して処理します(処理コードの場所はメソッドMessageProcessor.Process()に保持され、適切なコメントが表示されます).メッセージに疑問符が含まれている場合は、サーバは、応答メッセージを現在のすべてのサブスクライバにブロードキャストします.クライアントは、そのコンソールに応答を出力します.

    結論


    この作業はgRPCプログラムを用いる.NET 3.0同期双方向メッセージ・ストリームはインフラストラクチャを提供します.このインフラストラクチャを使用すると、特定のサーバとクライアントのコードを数行のコードに減らすことができます.
     
    原文住所:https://www.codeproject.com/Articles/5163307/Bidirectional-Messages-Streaming-with-NET-Core-3-0