SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

.NET最新版でASP.NET Core

ASP.NET CoreによるgRPCサーバの開発を理解しよう

.NET最新版でASP.NET Core 第10回

  • X ポスト
  • このエントリーをはてなブックマークに追加

環境構築について

 ASP.NET Core内でgRPCサポートが完結しているので、.NET環境を用意する以外の環境構築は基本的に不要です。ただ、汎用のgRPCクライアントを用意しておくと、クライアント構築前にサーバの動作を検証できるのでよいでしょう。以下のような汎用のgRPCクライアントがあります。

  • Evans
  • grpcurl

 Evansは、REPLモードを備えるなど使い勝手の良いgRPCクライアントですが、今回はMicrosoftの公式サイトでも言及しているgrpcurlを使って動作検証します。macOSやDcoker環境では、以下のインストール手順を参考にしてください。

 Windows環境などは、以下からダウンロードして、解凍してできる実行形式ファイルを適当な場所に配置して、コマンド名のみで実行できるようにしておきます。

サーバを構築する

 まずは、サーバを作っていきましょう。アプリケーションの名前はGrpcServerSampleとします。

サーバの作成と動作確認

 gRPCサーバも、これまでの回と同様にテンプレートから作成可能です。以下のdotnet newコマンドで作成します。

% dotnet new grpc -o GrpcServerSample -F net7.0

 コマンドの引数grpcは、gRPCサーバのテンプレートの指定です。-oオプションはファイルの書き出し先、-Fオプションは本稿作成時点での最新バージョンである.NET 7をターゲットにする指定です。この時点でdotnet runコマンドを実行すると、シンプルな機能を持ったgRPCサーバを直ちに起動できます。

% dotnet run -lp http
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5046
…略…

 -lpオプションは、使用するプロファイルの指定です。この場合、HTTPでリクエストを待機します。HTTPSで待機するには、-lpオプションにhttpsを指定しますが、macOS用の開発サーバはTLS上のHTTP/2通信をサポートしません。そのため、HTTPを指定しています。

 ここで、grpcurlでサーバの動作を見てみます。

% grpcurl -plaintext -proto Protos/greet.proto -d '{"name": "Nao"}' localhost:5046 greet.Greeter/SayHello 
{
  "message": "Hello Nao"
}

 指定されている引数及びオプションの意味は、以下の通りです。

  • localhost:5046:サーバとポートの指定
  • greet.Greeter/SayHello:呼び出す手続きの指定(パッケージ.サービス/手続き)
  • -plaintext:SSL(TLS)でないプレーンテキストでの通信を行う指定。サーバがHTTPSで待機しないので必須の指定となる
  • -proto:プロトコル定義ファイルの指定
  • -d:送信データの指定(JSON形式)

 いずれの意味も以降で明らかにしていくとして、ここでは、「"message": "Hello Nao"」を含むJSONデータが返ってくることを確認しましょう。

プロトコル定義ファイル

 既述の通り、gRPCではサーバとクライアントがやり取りするデータをProtocol Buffersという規格で定めています。Protocol Buffersでは、サーバが提供するサービス、手続き、データのフォーマットが規定され、それらをプロトコル定義ファイルに記述します。プロトコル定義ファイルは、プログラミング言語に依存しない書式になっており、このファイルを基に各プログラミング言語で使用するスタブファイル(クラスや構造体が定義されたファイル)が生成されるようになっています。以下は、既定で用意されるプロトコル定義ファイルです。

GrpcServerSample/Protos/greet.proto
// Protocol Buffers version 3を指定
syntax = "proto3";		(1)

// C#の名前空間を指定
option csharp_namespace = "GrpcServerSample";		(2)

// Protocol Buffersの名前空間(パッケージ)を指定
package greet;			(3)

// GreeterサービスとSayHello手続きを定義
service Greeter {		(4)
  rpc SayHello (HelloRequest) returns (HelloReply);	(5)
}

// 引数用のメッセージHelloRequestを定義
message HelloRequest {		(6)
  string name = 1;
}

// 戻り値用のメッセージHelloReplyを定義
message HelloReply {		(7)
  string message = 1;
}

 (1)は、このプロトコル定義ファイルがProtocol Buffersのバージョン3に準拠したものであることを示しています。Protocol Buffersにはバージョンが複数あり、本稿作成時点の最新版はバージョン3です。

 (2)は、プログラミング言語に特有のオプションの指定です。この場合は、C#言語の名前空間(csharp_namespace)を"GrpcSample"とするという指定です。この指定により、自動生成されるスタブファイルに記述される名前空間(namespace)が"GrpcServerSample"となります。

 (3)は、プロトコル定義ファイルのパッケージすなわち名前空間の指定です。この指定により、複数のプロトコル定義ファイルでの名前の衝突を回避します。

 (4)では、Greeterサービスを定義しています。ブロック内部にある(5)が、GreeterサービスにおけるSayHello手続きの定義です。SayHello手続きは、引数にHelloRequestメッセージを受け取り、HelloReplyメッセージを返すということがわかります。

 (6)と(7)は、(5)の定義で引数と戻り値に指定されたメッセージの定義です。HelloRequestメッセージは1個の文字列型のフィールドnameから構成され、HelloReplyメッセージは1個の文字列型のフィールドmessageから構成されることが分かります。右辺の「1」は、各フィールドを識別するための番号です。重複しない範囲で、任意の数値を指定します。

サービスのコードの確認

 次に、サービスのコードを見てみます。サービスのコードは、Servicesフォルダに置くことになっています。

GrpcServerSample/Services/GreeterService.cs
using Grpc.Core;		(1)
using GrpcServerSample;

namespace GrpcServerSample.Services;		(2)

public class GreeterService : Greeter.GreeterBase	(3)
{
    private readonly ILogger<GreeterService> _logger;		(4)
    public GreeterService(ILogger<GreeterService> logger)
    {
        _logger = logger;
    }

    public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)		(5)
    {
        return Task.FromResult(new HelloReply		(6)
        {
            Message = "Hello " + request.Name
        });
    }
}

 (1)は、必要な名前空間のインポートです。gRPCサーバで基本となるのは、Grpc.Net.Coreのみです。GrpcServerSampleは、プロトコル定義ファイルで指定したサーバ独自の名前空間です。スタブコードは、この名前空間内に作成されるので、この指定が必要となっています。

 (2)は名前空間の指定です。プロトコル定義ファイルで指定した"GrpcServerSample"に".Services"を付加したものが、名前空間として使用されます。

 (3)は、gRPCサービスGreeterに対応するクラスの定義です。継承元のクラスはスタブコードで定義されているGreeter.GreeterBaseです。このクラスに、サービス内の手続きを具体的に実装していきます。

 (4)は、ロガーとそれを外部から受け取って初期化するコンストラクタの定義です。既定では用意されているコンストラクタですが、利用しないならば省略可能です。実際に、Program.csにおけるGreeterServiceの生成ではデフォルトコンストラクタが用いられており、特にロガーは設定されていません。

 (5)は、サービス内の手続きSayHelloの具体的な実装です。このメソッドは、Unary形式の手続きの典型的なパターンであり、手続きの引数に指定されたHelloRequestオブジェクトとサーバが管理目的に使用するServerCallContextオブジェクトを引数に持ちます。戻り値は、Task<実際の戻り値型>すなわちTask<HelloReply>となります。

 (6)は、SayHelloメソッドの具体的な処理内容です。messageフィールドに"Hello "+request.Name(HelloRequestのnameフィールド)を設定したHelloReplyオブジェクトを生成し、TaskクラスのFromResultメソッドでTask型の値としてSayHelloメソッドの戻り値としています。なお、この部分は、以下のように文字列補間を使って書き換えると、現在のC#らしくなるでしょう。

Message = $"Hello {request.Name}"

まとめ

 今回は、ASP.NET CoreにおけるgRPCのサポートと、既定で作成できるgRPCサーバについて見てきました。次回は、このサーバを利用するクライアントの作成と、サーバサイドストリーミングに対応した手続きの実装を紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
.NET最新版でASP.NET Core連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18279 2023/09/26 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング