3.5.1 接口
一個簡單的接口定義:
service Foo {
rpc Bar(FooRequest) returns(FooResponse);
}
ProtocolBuffer的編譯器會生成類 Foo 來展示這個服務。 Foo 將會擁有每個服務定義的方法。在這種情況下 Bar 方法的定義是:
def Bar(self,rpc_controller,request,done)
參數等效於 Service.CallMethod() ,除了隱含的 method_descriptor 參數。
這些生成的方法被定義爲可以被子類重載。缺省實現只是簡單的調用 controller.SetFailed() 而拋出錯誤信息告之尚未實現。然後調用done回調。在實現你自己的服務時,你必須繼承生成類,然後重載各個接口方法。
Foo繼承了 Service 接口。ProtocolBuffer編譯器會自動聲響相關的實現方法:
· GetDescriptor :返回服務的 ServiceDescriptor 。
· CallMethod :檢測需要調用哪個方法,並且直接調用。
· GetRequestClass 和 GetResponseClass :返回指定方法的請求和響應類。
13.5.2 存根(Stub)
ProtocolBuffer編譯器也會爲每個服務接口提供一個存根實現,用於客戶端發送請求到服務器。對於Foo服務,存根實現是 Foo_Stub 。
Foo_Stub 是Foo的子類,他的構造器是一個 RpcChannel 。存根會實現調用每個服務方法的 CallMethod() 。
ProtocolBuffer哭並不包含RPC實現。然而,它包含了你構造服務類的所有工具,不過選擇RPC實現則隨你喜歡。你只需要提供 RpcChannel 和 RpcController 的實現即可。
1) 定義協議
首先需要爲這個service定義proto文件, 如下:
05 |
required
string message = 1 ; |
10 |
required
string response = 1 ; |
15 |
rpc
Echo(EchoRequest) returns (EchoResponse); |
解釋一下這個proto文件中做的事情,它定義了一個package: echo, 這個package中有service:EchoService,而這個service下只有一個服務:Echo, 它的請求由EchoRequest結構體定義,回覆由EchoResponse定義.
package相當於是C++中namespace的概念,有些package中可能會提供相同名字的service,爲了解決命名衝突,就引入了package這個概念.
2) 對應的C++文件
使用protobuf自帶的編譯proto文件編譯器,可以生成對應的pb.h和pb.cc文件.具體細節可以參考protobuf關於這部分的參考文檔.
所生成的C++文件,都會在namespace echo中,就是前面提到的package概念.對於service EchoService而言,會對應的生成兩個類:EchoService類和EchoService_Stub類:
01 |
c lass EchoService
: public ::google::protobuf::Service
{ |
03 |
EchoService_Stub(::google::protobuf::RpcChannel*
channel); |
04 |
virtual void Echo(::google::protobuf::RpcController*
controller, |
05 |
const ::echo::EchoRequest*
request, |
06 |
::echo::EchoResponse*
response, |
07 |
::google::protobuf::Closure*
done); |
08 |
void CallMethod( const ::google::protobuf::MethodDescriptor*
method, |
09 |
::google::protobuf::RpcController*
controller, |
10 |
const ::google::protobuf::Message*
request, |
11 |
::google::protobuf::Message*
response, |
12 |
::google::protobuf::Closure*
done); |
15 |
class EchoService_Stub
: public EchoService
{ |
17 |
void Echo(::google::protobuf::RpcController*
controller, |
18 |
const ::echo::EchoRequest*
request, |
19 |
::echo::EchoResponse*
response, |
20 |
::google::protobuf::Closure*
done); |
上面省略了一些細節,只把最關鍵的部分提取出來了.
這兩部分如何使用,後面會繼續講解