サービス

インターフェース

サービス定義が与えられると:
service Foo {
  rpc Bar(FooRequest) returns(FooResponse);
}
プロトコルバッファコンパイラは、このサービスを表現した Fooクラスを生成します。 Fooはサービス定義で宣言されたメソッドのそれぞれの仮想関数を持っています。 この場合は、Barメソッドが次のように定義されます:
virtual void Bar(RpcController* controller, const FooRequest* request,
                 FooResponse* response, Closure* done);

method引数が暗黙に指定されていることと、requestresponse が正確な型を指定していることを除き、このメソッドのパラメータは、Service::CallMethod() と同じです。

これらの生成されたメソッドは仮想関数ですが、純粋仮想関数ではありません。 デフォルトの実装は単純にメソッドが未実装であることを示すエラーメッセージで controller->SetFailed() を呼んで、done のコールバックを呼ぶだけです。 あなたの独自のサービスを実装するときは、この生成されたサービスのサブクラスを作り、メソッドを適切に実装しなければなりません。

FooServiceインターフェースのサブクラスです。以下のように、プロトコルバッファコンパイラは Service のメソッドの実装を自動的に生成します。
GetDescriptor
サービスの ServiceDescriptor を返します。
CallMethod
どのメソッドを呼ぶかを与えられたメソッドディスクリプタに基づいて決定し、request, response のメッセージオブジェクトを正しい型へダウンキャストして、決定したメソッドを直接呼び出します。
GetRequestPrototypeGetResponsePrototype
与えられたメソッドの正しい型の request と response のデフォルトインスタンスを返します。
次の静的メソッドも生成します:
static ServiceDescriptor descriptor()
このサービスがどんなメソッドを持っているのかと、それらの入出力の型が何なのかの情報を含む、この型のディスクリプタを返します。

スタブ

プロトコルバッファコンパイラは、全てのサービスインターフェースの「スタブ」実装も生成します。 これは、サービスを実装したサーバーへリクエストを送りたいクライアントで利用されます。 (上記の)Fooサービスには、スタブ実装の Foo_Stub が定義されます。 ネストされたメッセージ型の場合には、Foo_StubFoo::Stub としても参照できるように typedef が使われます。

Foo_StubFoo のサブクラスで、次のメソッドを実装しています:
Foo_Stub(RpcChannel* channel)
与えられたチャネルでリクエストを送信する新たなスタブを構築します。
Foo_Stub(RpcChannel* channel, ChannelOwnership ownership)
与えられたチャネルでリクエストを送信し、そのチャネルを所有することができる新たなスタブを構築します。ownershipService::STUB_OWNS_CHANNEL の場合、スタブオブジェクトが消去される時にチャネルも消去されます。
RpcChannel* channel()
コンストラクタで渡された、このスタブのチャネルを返します。

スタブは、チャネルのラッパとして個々のサービスメソッドを追加実装します。 このメソッドの呼び出しは、単に channel->CallMethod() を呼び出します。

プロトコルバッファライブラリは RPC 実装を含んでいません。 ですが、生成されたクラスからあなたの選んだ任意の RPC実装へと中継するのに必要な全ての道具を含んでいます。 あなたは RpcChannelRpcController の実装を提供する必要があるだけです。詳しい情報は、service.h のドキュメントを見てください。