投稿日:2025/02/17

gRPCを使った高速で簡単な通信

   

こんにちは!
代表兼プログラマーの川本です。

以前、プロセス間通信の記事を上げていますが、通信には様々な手法が存在しています。

今回は昨今のゲームでも利用事例のあるgRPCを使った通信プログラムについて記載していきます。

gRPCについて

gRPC(gRPC Remote Procedure Call)は、Googleが開発したオープンソースのRPC(Remote Procedure Call)フレームワークです。
HTTP/2をベースとし、高速でスケーラブルな通信を可能にするプロトコルとして、多くのシステムで採用されています。
また、Protocol Buffers(protobuf)を使用して通信データをシリアライズするため、従来のJSONやXMLよりも高速かつ効率的なデータ転送が可能です。

gRPCの主な特徴
  • HTTP/2を使用し、効率的な通信を実現
  • Protocol Buffersを利用した軽量なデータフォーマット
  • 双方向のストリーミング通信をサポート
  • 多言語対応(Python, C#, Java, Go, Rust など)
ゲーム開発での利用事例

株式会社Cysharpから公開されているOSS「MagicOnion」でも採用されています。
MagicOnionはUnityを活用した様々なゲーム開発でも活用されています。
※MagicOnionはC#向けに最適化されている

gRPCのメリット・デメリット

メリット
  • 高速な通信: HTTP/2とProtocol Buffersにより、低レイテンシかつ高速なデータ転送が可能
  • スケーラビリティ: ストリーミング対応や負荷分散に適している
  • 多言語対応: 異なるプログラミング言語間でシームレスな通信が可能
  • API設計の統一: .protoファイルを基に自動生成されるコードで開発を効率化
デメリット
  • 学習コスト: REST APIに比べると、.protoファイルやgRPCの概念を理解する必要がある
  • デバッグの難しさ: JSONと異なり、Protocol Buffersのデータは可読性が低いためデバッグが難しい
  • ブラウザとの直接通信が難しい: gRPC-Webを使わないとブラウザでの直接通信ができない

 

gRPCの仕組み

gRPCの基本的な仕組みは、クライアントとサーバー間でのRPC(Remote Procedure Call)通信です。
サーバーは特定のサービスを提供し、クライアントはそのサービスを呼び出すことでデータを送受信します。

gRPCの通信モデル

gRPCは以下の4つの通信モデルを提供します。

Unary RPC クライアントがリクエストを送り、サーバーがレスポンスを1回返す
Server Streaming RPC クライアントが1つのリクエストを送り、サーバーが複数のレスポンスをストリームとして送る
Client Streaming RPC クライアントが複数のリクエストをストリームで送り、サーバーが1つのレスポンスを返す
Bidirectional Streaming RPC クライアントとサーバーが双方向にストリーミング通信を行う

 

PythonとC#間でgRPC接続

ここでは、PythonのgRPCサーバーとC#のgRPCクライアントを実装して、異なる言語間での通信を実現します。

1. protoファイルの作成

まず、通信のインターフェースを定義する `.proto` ファイルを作成します。

  1. syntax = "proto3";
  2.  
  3. service Greeter {
  4. rpc SayHello (HelloRequest) returns (HelloReply);
  5. }
  6.  
  7. message HelloRequest {
  8. string name = 1;
  9. }
  10.  
  11. message HelloReply {
  12. string message = 1;
  13. }

このファイルを基に、PythonやC#のgRPCコードを自動生成します。

 

2. Python用のgRPCコード生成

pythonでgRPCコードの生成とサーバーを起動するには以下のコマンドでモジュールのインストールが必要になります。

  1. pip install grpcio
  2. pip install grpcio-tools

次にgrpcio-toolsを使ってprotoファイルからコードを生成します。

  1. python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. greeter.proto

 

このコマンドを実行すると、以下の2つのファイルが生成されます。

  • `greeter_pb2.py`: メッセージのシリアライズ/デシリアライズを担当
  • `greeter_pb2_grpc.py`: gRPCのクライアントとサーバーのスタブを提供
3. PythonでgRPCサーバーを作成
  1. from concurrent import futures
  2. import grpc
  3. import greeter_pb2
  4. import greeter_pb2_grpc
  5.  
  6. class GreeterServicer(greeter_pb2_grpc.GreeterServicer):
  7. # クライアントから呼び出す関数
  8. def SayHello(self, request, context):
  9. # クライアント側に返すレスポンスデータ
  10. return greeter_pb2.HelloReply(message=f"Hello, {request.name}!")
  11.  
  12. def serve():
  13. server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
  14. greeter_pb2_grpc.add_GreeterServicer_to_server(GreeterServicer(), server)
  15. # ポート番号の指定
  16. server.add_insecure_port('[::]:50051')
  17. server.start()
  18. server.wait_for_termination()
  19.  
  20. if __name__ == '__main__':
  21. serve()

このスクリプトを実行することで、PythonのgRPCサーバーが起動します。

4. C#でgRPCクライアントを作成

次に、C#でgRPCクライアントを作成し、Pythonサーバーと通信を行います。

  1. using System;
  2. using System.Threading.Tasks;
  3. using Grpc.Net.Client;
  4. using Greeter;
  5.  
  6. class Program
  7. {
  8. static async Task Main(string[] args)
  9. {
  10.      // Python側(gRPCサーバー)へのURLを指定
  11. using var channel = GrpcChannel.ForAddress("http://localhost:50051");
  12. var client = new Greeter.GreeterClient(channel);
  13. // Python(サーバー)のSayHello関数を呼び出し
  14. var reply = await client.SayHelloAsync(new HelloRequest { Name = "C# Client" });
  15. Console.WriteLine("Server Response: " + reply.Message);
  16. }
  17. }

このコードを実行すると、Pythonサーバーにリクエストを送り、レスポンスを受け取ることができます。

5. 実行結果

C#クライアントを実行すると、以下のような出力が得られます。

  1. Server Response: Hello, C# Client!

これで、PythonサーバーとC#クライアント間のgRPC通信が成功しました。

手順は複数ありますが、コードだけで見ると

  • Python(サーバー側):21行(メインコードは約10行)
  • C#(クライアント側):17行(通信コードは3行)

とたったこれだけで通信機能を実装する事が出来ます。

 

まとめ

gRPCは、高速かつ効率的な通信を可能にする強力なフレームワークです。
特に、異なるプログラミング言語間での通信が求められる場面では、gRPCを活用することでスムーズなデータのやり取りが可能になります。
今回はPythonとC#間の接続を実装しましたが、他の言語でも同様の方法で接続が可能です。

これはゲームに限らず有効な通信手段の1つとして上げられます。

是非、実際に試してみてください!