protobuf service详解
这里写目录标题定义serviceUserServiceRpc类 和 UserServiceRpc_stub类UserServiceRpc类成员分析定义service.proto文件的代码如下:syntax = "proto3"; // 声明了protobuf的版本package fixbug; // 声明了代码所在的包(对于C++来说是namespace)//定义下面的选项,表示生成service
这里写目录标题
定义service
.proto文件的代码如下:
syntax = "proto3"; // 声明了protobuf的版本
package fixbug; // 声明了代码所在的包(对于C++来说是namespace)
//定义下面的选项,表示生成service服务类和rpc方法描述,默认不生成
option cc_generic_services = true;
message ResultCode//封装一下失败类
{
int32 errcode = 1;//表示第1字段
bytes errmsg = 2;//表示第2字段
}
// 定义登录请求消息类型 name pwd
message LoginRequest
{
bytes name = 1;//表示第1字段
bytes pwd = 2;//表示第2字段
}
// 定义登录响应消息类型
message LoginResponse
{
ResultCode result = 1;//表示第1字段
bool success = 2;//表示第2字段
}
//在protobuf里面怎么定义描述rpc方法的类型 - service
service UserServiceRpc
{
rpc Login(LoginRequest) returns(LoginResponse);
}
其中,涉及到service的部分如下:
//定义下面的选项,表示生成service服务类和rpc方法描述,默认不生成
option cc_generic_services = true;
//在protobuf里面怎么定义描述rpc方法的类型 - service
service UserServiceRpc
{
rpc Login(LoginRequest) returns(LoginResponse);
}
UserServiceRpc类 和 UserServiceRpc_stub类
对上文的.proto文件保存并编译,得到一个.pb.h和一个.pb.cc文件,包含UserServiceRpc类和UserServiceRpc_stub类。
UserServiceRpc类分析
UserServiceRpc类是因为在.proto文件中定义了UserServiceRpc服务而生成的,UserServiceRpc类继承于google::protobuf::Service类,如下所示:
UserServiceRpc类成员如下:
class UserServiceRpc : public ::PROTOBUF_NAMESPACE_ID::Service {
protected:
// This class should be treated as an abstract interface.
inline UserServiceRpc() {};
public:
virtual ~UserServiceRpc();
typedef UserServiceRpc_Stub Stub;
static const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor* descriptor();
virtual void Login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done);
// implements Service ----------------------------------------------
const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor* GetDescriptor();
void CallMethod(const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method,
::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::PROTOBUF_NAMESPACE_ID::Message* request,
::PROTOBUF_NAMESPACE_ID::Message* response,
::google::protobuf::Closure* done);
const ::PROTOBUF_NAMESPACE_ID::Message& GetRequestPrototype(
const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method) const;
const ::PROTOBUF_NAMESPACE_ID::Message& GetResponsePrototype(
const ::PROTOBUF_NAMESPACE_ID::MethodDescriptor* method) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UserServiceRpc);
};
- Login()虚函数,让派生类重写。我们看到,Login虚函数的名字就是我们定义的rpc服务的方法的名字,其有4个固定的参数。
- GetDescriptor()函数,获得一个指向ServiceDescriptor类型对象的指针,ServiceDescriptor类型的对象中描述了rpc方法的名字(属于哪一个类类型的方法)和调用函数方法的参数。
UserServiceRpc_stub类分析
UserServiceRpc_stub类继承了UserServiceRpc类,并重写了UserServiceRpc类中的虚函数Login()。
UserServiceRpc_stub类成员如下:
class UserServiceRpc_Stub : public UserServiceRpc {
public:
UserServiceRpc_Stub(::PROTOBUF_NAMESPACE_ID::RpcChannel* channel);
UserServiceRpc_Stub(::PROTOBUF_NAMESPACE_ID::RpcChannel* channel,
::PROTOBUF_NAMESPACE_ID::Service::ChannelOwnership ownership);
~UserServiceRpc_Stub();
inline ::PROTOBUF_NAMESPACE_ID::RpcChannel* channel() { return channel_; }
// implements UserServiceRpc ------------------------------------------
void Login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done);
private:
::PROTOBUF_NAMESPACE_ID::RpcChannel* channel_;
bool owns_channel_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UserServiceRpc_Stub);
};
- 其拥有一个RpcChannel类型的指针变量,在构造时需要传入这个值(没有默认构造函数!)。
- 其Login()是继承自基类的函数,其调用了channel的CallMethod函数,Login()的实现如下:
void UserServiceRpc_Stub::Login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done) {
channel_->CallMethod(descriptor()->method(0),
controller, request, response, done);
}
Rpcchannel类
Rpcchannel是一个抽象类!其包含一个CallMethod()虚函数。
Rpcchannel类代码如下:
因此我们必须自己去实现一个类,这个类从Rpcchannel继承而来,并重写CallMethod()虚函数。即:

由于派生类是可以用基类指针的(多态),因此stub桩类不管调用哪个方法,最终都调用到我们的MyRpcChannel的CallMethod方法,我们在这里就可以进行rpc方法的序列化和反序列化,然后发起远程的rpc调用请求。所以框架的实现重点就在于RpcChannel的CallMethod方法。
更多推荐



所有评论(0)