箱庭PDUアーキテクチャ(その6:RPC編)


前回は、箱庭PDUの構造を一旦立ち止まって振り返りました。
特に「PDUは通信方式に縛られるべきではない」という基本的な設計原則から始まり、
データ定義・通信プロトコル・転送制御 の責務を明確に切り分ける構造に整理しました。

そして、今回は、箱庭RPCの解説をしたいと思います。

そもそも、RPC とは何か。

RPCって、Remote Procedure Callの略なんです。

日本語にすると、「遠隔手続き呼び出し」となります。

ただ、この翻訳だけで見ると、
「ある手続き(一般的には関数)をネットワーク越しに呼び出すこと」
くらいの意味に見えて、少しそっけないですよね。

そこで、もう少し踏み込んで言うと、
RPCは、

離れた場所にある処理を、
あたかも手元で実行しているかのように扱いたい

というモチベーションから生まれた技術です。

ここで重要なのは、
RPCが解決しようとしているのは 通信そのもの ではなく、
「分散した処理を、どう“ひとつの操作”として扱うか」 という点です。

単にデータを送って、返ってくる、という話ではありません。

  • 要求を送る
  • 相手がそれを処理する
  • 結果が返ってくる
  • その一連の流れが「1回の呼び出し」として成立する

この 要求と応答の関係性 を、
プログラム上で自然に扱えるようにするのがRPCです。

現代的な例:MCP も RPC である

たとえば、最近流行りの MCP(Model Context Protocol)も、
基本的な構造は RPC と同じです。

  • クライアントが要求を送り、
  • サーバがそれを解釈・処理し、
  • 結果をレスポンスとして返す。

利用者の視点では、
「遠くで何が起きているか」を強く意識する必要はありません。

あたかも
手元の関数を呼び出しているかのように使える
──これがRPCの本質です。

少し昔話:Sun RPCの時代

ちなみに、ぼくが新入社員の頃に使っていたのは、Sun RPC でした。

Sun RPC(別名: ONC RPC – Open Network Computing RPC)。

正式には以下のように呼ばれていました:

  • Sun RPC (一般的な呼び方)
  • ONC RPC (Open Network Computing RPC – Sunが標準化を目指した際の名称)
  • RPC/XDR (XDR = eXternal Data Representationとセットで語られることも)

特徴的だった要素としては、

  • rpcgen というコンパイラでスタブコードを自動生成
  • XDR(外部データ表現)でデータをシリアライズ
  • portmapper(後のrpcbind)でサービス検索
  • NFSの基盤技術として広く普及

といった点です。
1980年代から1990年代のUnix環境では、 事実上の標準でした。懐かしい技術です。

その後、
CORBA、SOAP、そして現代の gRPC へと進化していきましたが、
「インターフェース定義言語(IDL)からコードを生成する」
という Sun RPC の思想は、今も確実に受け継がれています。

ロボティクスの世界では:ROS Service

そして、この RPC の流れは、
ロボティクス分野では ROS にも見ることができます。

ROS には、

  • Topic:一方向のデータ配信
  • Service:要求と応答によるRPC
  • Action:時間のかかるRPC(途中経過・キャンセル可能)

といった通信モデルがあります。

特に ROS Service は、

  • .srv ファイルでインターフェースを定義し
  • コードを自動生成し
  • クライアント側からは、関数呼び出しのように使える

という点で、
Sun RPC から続く 王道的なRPC設計 を、そのまま受け継いでいます。

分散シミュレーション・ハブ箱庭の世界では:箱庭 RPC

箱庭も、この RPC の系譜に連なっています。

箱庭RPCは、ロボティクスシミュレーションという文脈で、

  • 複数のシミュレータ間の連携
  • 異なる言語で書かれたコンポーネント間の通信
  • リアルタイム性を保ちながらの分散処理

を実現するために設計されました。

箱庭RPCの特徴

ROS Service と同様に、箱庭RPCも:

  • .srv ファイルでインターフェースを定義し
  • コードを自動生成し
  • クライアント側からは、関数呼び出しのように使える

という王道的なRPC設計を採用しています。

この点だけを見ると、
箱庭RPCは「ROS Serviceとよく似た仕組み」に見えるかもしれません。

しかし、箱庭RPCには、ひとつ大きな特徴があります。

それは、前回整理したPDU設計と、最初から統合されているという点です。

箱庭RPCでは、次のような責務分離が行われています。

  • データ定義
    .srv ファイルで定義されたインターフェースは、
    箱庭内部では PDUデータとして変換・扱われます
  • RPC通信プロトコル
    要求・応答・キャンセルといった
    RPCとしての制御ロジック(call / cancel / reply)は、
    箱庭の通信ライブラリとして提供されます
  • 通信方式
    RPCの通信プロトコルは 通信方式に依存せず
    実際の送受信は PDUエンドポイント に委ねられます

この結果、

  • RPCは「対話モデル」に集中でき
  • PDUは「データ表現と転送」に専念し
  • 通信方式(共有メモリ、TCP、UDPなど)は、後から自由に差し替えられる

という、明確な関心の分離が実現されています。

これは、前回整理した
「PDUは通信方式に縛られるべきではない」
という設計原則を、そのままRPCの世界に拡張したものでもあります。

悩みました。

分散シミュレーションでは、RPCを使いたいシーンが色々あります。
箱庭の文脈(箱庭コンダクター)で言えば、

  • 箱庭アセットの登録を遠隔から行う
  • サーバーのイベントや状態を取得する
  • ノード間で「問い合わせ → 応答」のやり取りを確実に成立させる

といった用途ですね。

だから、昔の箱庭コンダクターの実装では gRPC を使っていました。

gRPCは確かに便利です。Googleがメンテナンスしているという安心感もあります。

ただ、実運用の目線で見ると、つらい点がありました。

  • バージョン差でコンパイルできないことがある
  • GitHubからコードを落として ビルドする手間が重い
  • gRPC自体を インストールする前提が増える
  • 依存関係が大きく、環境差の吸収にコストがかかる

「とにかく早く動かして試したい」という開発フェーズほど、
こうした点が地味に足枷になるんです。

さらに、箱庭は Unity とも組み合わせたい。
しかし Unity は、少なくとも “公式に gRPC を強く推している” という状態ではありません。

つまり、箱庭の世界観で gRPC を採用するのは、

  • 技術としては正しいが
  • 運用・配布・開発体験としては重い

という結論になっていきました。

だから、やっぱり使いたくないな、と思ったんですね。

そこで、箱庭では PDUという土台がすでにある ことを活かして、
「箱庭のための、軽いRPC」を作ることにしました。

箱庭RPCの設計

こちらが、箱庭RPCの設計です。

まず強調しておきたいのは、
箱庭RPCは 「RPCサービスそのもの」よりも、「RPCサービス設定」を中心に据えた設計 になっている、という点です。

箱庭RPCサービスとサービス設定

図の一番上にあるのが 箱庭RPCサービス です。

これは、
「どんなRPCを提供するか」
という 論理的なサービス定義 を表しています。

そして、その下にある 箱庭RPCサービス設定 が、
実際の通信を成立させるための 中核コンポーネント です。

  • どのサーバーがこのRPCを提供するのか
  • どのクライアントが、このRPCを呼び出せるのか
  • Request / Response に使うPDUは何か

といった情報は、すべてこの RPCサービス設定 に集約されます。

サーバーとクライアントの関係

図の左側が サーバー、右側が クライアント です。

  • 1つのRPCサービス設定に対して
    • サーバーは1つ
    • クライアントは1つ以上(1..*)

という関係になります。

これは、
「1つのサービスを、複数のクライアントから呼び出せる」
という、RPCとして自然なモデルです。

Request / Response とPDUエンドポイント

RPCサービス設定から下に伸びている矢印が、
Request : 1 / Response : 1 です。

箱庭RPCでは、

  • 1回のRPC呼び出しにつき
    • Request PDU が1つ
    • Response PDU が1つ

という 明確な1対1対応 を採用しています。

そして、実際の送受信は、
すべて 箱庭PDUエンドポイント を通じて行われます。

ここが重要なポイントです。

RPCはあくまで
「要求と応答という対話モデル」 を提供するだけで、
通信方式(TCP / UDP / 共有メモリなど)には一切依存しません。

なぜこの構造なのか

この設計によって、箱庭RPCでは、

  • RPCの設計は 対話モデルに集中 できる
  • データ表現と転送は PDUに任せる
  • 通信方式は PDUエンドポイントの差し替えで変更可能

という、前回整理した PDU設計の思想 を、そのままRPCにも持ち込むことができています。

つまりこの図は、

「RPCを、PDUの上に“自然に載せた”結果」

そのものなんですね。

チュートリアルを公開中。

箱庭RPCは、現在 チュートリアルを公開中 です。

この箱庭RPCのリポジトリは、以下で公開しています。

また、チュートリアルとして、
単純な足し算サービス(AddTwoInts) を例に、
箱庭RPCの基本的な使い方を解説しています。

  • RPCサービスの定義
  • サーバー側の実装
  • クライアント側の呼び出し
  • Request / Response の流れ

を、最小構成で確認できる内容になっています。

チュートリアルはこちらです。

つづく。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

PAGE TOP