こんにちは。
Developer Support Internet チーム にてインターンをしている尾崎耀一と申します!
今回は ASP.NET Core を用いて、 gRPC で動く CLI (コマンドライン)でチャットができるアプリを作る方法を紹介します。
本記事を通じて、 ASP.NET Core を用いた gRPC サービスの開発が簡単にできることがわかると思います。
皆様の開発の一助になると幸いです。
まずはチャット アプリを作る前に ASP.NET Core についてご紹介します。
ASP.NET Core について
ASP.NET Core はクロスプラットフォームで動作するウェブアプリケーションフレームワークです。
ASP.NET Core を用いることで簡単にウェブアプリを開発することができます。加えて、 ASP.NET Core はクロスプラットフォームに対応しているので、 Windows/macOS/Linux 上で開発・実行することができます。
ASP.NET Core はオープンソースで開発が進められており、 ASP.NET Core コミュニティーは大きく成長しています。
ASP.NET Core はモダンなウェブ開発をフレームワークとしてサポートしています。テストが容易に実行できるようなアーキテクチャを採用しており、クラウドへのデプロイなども想定し Visual Studio などのエディタも用意されています。
また、最新の技術にも対応しています。 例えば、gRPC によるリモート プロシージャ コールのサポートや WebAssemby によって SAP(Single Page Application)を C# で開発する Blazor というフレームワークもサポートしています。
公式ドキュメントにもあるように、ASP.NET Core には次のような利点があります。
- Web UI と Web API を構築するプロセスの統一。
- テストの容易性を考慮したアーキテクチャ。
- Razor Pages により、ページ コーディングに重点を置いたシナリオがより簡略化され、その生産性が高められます。
- Blazor により、ブラウザー内で JavaScript と共に C# を使用できます。 すべて .NET で記述された、サーバー側とクライアント側アプリのロジックを共有します。
- Windows、macOS、Linux 上で開発および実行できること。
- オープン ソースでコミュニティ重視。
- 最新のクライアント側フレームワークと開発ワークフローの統合。
- gRPC を使用したリモート プロシージャ コール (RPC) サービスのホストのサポート。
- クラウド対応で環境ベースの構成システム。
- 組み込まれている依存性の注入。
- 軽量で高パフォーマンスのモジュール化された HTTP 要求パイプライン。
- 次がホストする機能です。
- side-by-side でのバージョン管理。
- 最新の Web 開発を簡単にするツール。
ASP.NET Core 公式ドキュメントより抜粋
参考:ASP.NET Core 公式ドキュメント
参考:ASP.NET Coreについて
gRPC について
次に、 gRPC についてご紹介します。
gRPC は言語に依存しない高性能なリモート プロシージャ コール(RPC)フレームワークです。
gRPC を用いることで、やり取りされるデータのシリアライズ・デシリアライズや通信部分はフレームワーク側がカバーしてくれるため、アプリケーション開発者はプロシージャを呼び出すクライアントと呼び出されるサーバプロシージャのみを実装すれば良いということになります。
gRPC ではデータのシリアライズに Protocol Buffers をデフォルトでは採用しています。Protocol Buffers はサービス間のインタフェースを定義する言語とそれを書くプログラミング言語のプログラムにコンパイルするツール群を含んでいます。Protocol Buffers では、公開する関数 (リモートプロシージャ) や、やり取りするデータの型を .proto
ファイルにて定義し、 .proto
ファイルからデータをシリアライズするプログラムのソースコードを自動生成することができ、対応する言語も C++/C#/Go/Java/Python etc… と豊富です。サービス間のインタフェースをコードとして静的に定義することが可能であるため、ソースコードの生成のみならず、ドキュメントの自動生成などもできます。
また、gRPC には次のような特徴を持ちます。
- Protocol Buffers を内部で用いているので他言語でのサーバ・クライアントの開発が可能です。
- HTTP/2 による通信を行います。ゆえに双方向ストリーミング通信もサポートしています。
- その手軽さと利便性から Netflix などでも採用されており、今後もユースケースの増加が見込まれます。
参考:gRPC 公式サイト
参考:Protocol Buffers 公式サイト
Hands-on:CLI Chat アプリ
今回は gRPC で通信する Chat サーバと Chat クライアントを ASP.NET Core を用いて実装します。さらに gRPC で通信する Chat クライアントを C# とは別の言語(今回は go 言語)で実装し、 gRPC の「プログラミング言語に依存しない」という特徴も確認します。 ASP.NET Core を用いた gRPC サービスの開発が非常に容易であることも実感できると思います。
環境
以下の内容は以下の環境にて検証しました。
- OS:Windows 10 Enterprise バージョン 1903
- IDE:Visual Studio 2019
- Platform:.NET Core 3.1.401
Visual Studio のインストールはこちらを参考にしてください。
今回作成する Chat サービスのインターフェース定義
今回の Chat サービスでは、ChatRoom
が一つあり、そこにユーザが Join
することで Message
のやり取りができるものを考えます。
ユーザは一度 ChatRoom
に Join
すると、その ChatRoom
内での他のユーザの発言を知る必要があるため、Chat サーバ-Chatクライアント間には Message
の流れる双方向ストリームが必要になります。
これを、 chat.proto
として記述すると以下のようになります。
1 | syntax = "proto3"; |
gRPC で通信する Chat サーバを ASP.NET Core で実装する
まず Visual Studio を立ち上げ、「新しいプロジェクトの作成」から gRPC サービスのテンプレートを選択し、テンプレートプロジェクト(プロジェクト名: GrpcChatServer
)を作成します。
このとき、出来上がるテンプレートプロジェクトは、公式ドキュメントのチュートリアルにおける、「 Greeter サービス」と同じものです。このテンプレートプロジェクトには、 Grpc.AspNetCore (2.31.0)
という ASP.NET Core で gRPC アプリケーションを作成するために必要なパッケージがインストール済みです。
このテンプレートに手を加えて、 Chat サービスを実装していきます。
まず最初に、 chat.proto
を GrpcChatServer/Protos
にコピーします。続けて、 GrpcChatServer.csproj
に下記 <ItemGroup>
を追加します。ここで GrpcServices="Server"
と記載することで、 .proto
ファイルから gRPC サーバ用のコードが自動生成されることになります。
1 | <ItemGroup> |
次に、 ChatRoom
クラスを ChatRoom.cs
に記述します。
1 | using Chat; |
上で定義した ChatRoom
を利用する ChatService
を ChatService.cs
に記述します。このとき、 ChatService
クラスは gRPC によって自動生成された ChatRoomBase
クラス ( .proto
ファイルの Service
に指定した名前の後に Base
を付与して自動生成されるクラス) を継承する形で実装します。こうすることで、 Chat サービスを実装する際の通信回りの実装を基底クラスに委譲して、アプリ実装者はアプリケーションのロジックに専念することができるようになります。
1 | using System.Collections.Generic; |
以上で定義した ChatRoom
および ChatService
を Startup.cs
にて登録することで Chat サーバは完成です。
1 | using System; |
このように、 ASP.NET Core を用いて gRPC サービスを実装する際には、データのシリアライズや通信回りの実装を自動生成されたコードに委譲し、アプリケーション固有のロジックの実装に専念することができるようになります。
gRPC で通信する Chat クライアントを ASP.NET Core で実装する
Visual Studio を立ち上げ、「新しいプロジェクトの作成」から「コンソールアプリ(.NET Core)」を選択し、テンプレートプロジェクト(プロジェクト名: GrpcChatClient
)を作成します。
まず最初に以下の三つのパッケージを GrpcChatClient
にインストールします。
Google.Protobuf (2.31.0)
Grpc.Net.Clien (2.31.0)
Grpc.Tools (2.31.0)
つづけて、 GrpcChatClient
プロジェクト内に Protos
フォルダを作成し、GrpcChatServer
と同じ chat.proto
ファイルをコピーし、 GrpcChatClient.csproj
に以下の <ItemGroup>
を追加します。ここでも同様にGrpcServices="Client"
と記載することで、 .proto
ファイルから gRPC クライアント用のコードが自動生成されることになります。
1 | <ItemGroup> |
最後に、 Program.cs
に Chat クライアントのコードを記述してクライアントの実装は終了です。クライアントの実装では、サーバの実装と同様に gRPC によって自動生成されたクライアント用コードを using
することで用います。
1 | using System; |
ここまで終了したら、いよいよサーバとクライアントを通信させることができます。
複数コマンドプロンプトを立ち上げて、サーバとクライアントをそれぞれ実行し、通信することができるかを確かめてみましょう。
(画像右半分がサーバアプリの画面、画像左半部がクライアントアプリの画面)
gRPC で通信する Chat クライアントを go で実装する
gRPC は、サービスのインタフェースが Protocol Buffer という、プログラミング言語とは独立した形で記述されることから、互いに異なるプログラミング言語を用いてサーバとクライアントを開発することが容易であるという特徴があります。
そこで、ここまでで開発した Chat サーバと通信する Chat クライアントを C# とは別の Go という言語で開発してみましょう。なお、今回はあくまで検証用のサンプルのご紹介であり、go 言語のサンプルアプリのサポートや以下の環境構築に関するサポートは弊社では行っておりませんことご了承ください。
Windows における Go/gRPC 開発環境の構築については下記サイトなどを参考に行ってください。
参考:https://golang.org/doc/install
参考:https://grpc.io/blog/installation/
Go でのクライアント実装でも、コマンドで通信部分のソースコードを自動生成し、それを利用する形でクライアントを記述していくことには変わりありません。
Chat クライアントの Go 実装については下記リポジトリを参考にしてください。
Go クライアントリポジトリ:https://github.com/jpdsi/GrpcChatSample/tree/master/GrpcChatClientGo/chat
実際に通信させてみる
Go 実装のクライアントと C# 実装のクライアント、 C# 実装のサーバを立ち上げ実際に通信できることを確認してみます。
(画像右上がサーバアプリの画面、画像下半分が C# クライアントアプリの画面、画像左上が Go クライアントアプリの画面)
このように、 gRPC では異なる言語によるサーバ・クライアントの実装が容易に実現することができます。
今回作ったチャットアプリのコードは以下のリポジトリにあります。
リポジトリ:https://github.com/jpdsi/GrpcChatSample
他のサンプルも見てみたい方へ
今回は gRPC を使った Chat サービスを ASP.NET Core を利用して実装してみました。
gRPC では他にも様々な通信をサポートしており、 ASP.NET Core による実装例も以下のリポジトリから確認することができます。
ASP.NET Core を利用した gRPC 開発を検討の際には、開発したいものに合わせたサンプルを参照すると、参考になるかと思います。
サンプルリポジトリ:https://github.com/grpc/grpc-dotnet/tree/master/examples
今回は以上です。
ASP.NET CoreでgRPCを簡単に実装できることがお分かりいただけましたでしょうか?
それでは、また次回!
なお、本ブログは弊社の公式見解ではなく、予告なく変更される場合があります。
もし公式な見解が必要な場合は、弊社ドキュメント (https://docs.microsoft.com/ や https://support.microsoft.com) をご参照いただく、もしくは私共サポートまでお問い合わせください。