简介
brpc主要是通过Protocol这个接口来支持多协议的。其提供了解析,序列化,处理请求与响应的函数指针,通过函数指针以达到多态的效果
Protocol
结构体定义如下
struct Protocol {
typedef ParseResult (*Parse)(butil::IOBuf* source, Socket *socket,
bool read_eof, const void *arg);
Parse parse;
typedef void (*SerializeRequest)(
butil::IOBuf* request_buf,
Controller* cntl,
const google::protobuf::Message* request);
SerializeRequest serialize_request;
typedef void (*PackRequest)(
butil::IOBuf* iobuf_out,
SocketMessage** user_message_out,
uint64_t correlation_id,
const google::protobuf::MethodDescriptor* method,
Controller* controller,
const butil::IOBuf& request_buf,
const Authenticator* auth);
PackRequest pack_request;
typedef void (*ProcessRequest)(InputMessageBase* msg);
ProcessRequest process_request;
typedef void (*ProcessResponse)(InputMessageBase* msg);
ProcessResponse process_response;
typedef bool (*Verify)(const InputMessageBase* msg);
Verify verify;
typedef bool (*ParseServerAddress)(butil::EndPoint* out,
const char* server_addr_and_port);
ParseServerAddress parse_server_address;
typedef const std::string& (*GetMethodName)(
const google::protobuf::MethodDescriptor* method,
const Controller*);
GetMethodName get_method_name;
ConnectionType supported_connection_type;
const char* name;
bool support_client() const {
return serialize_request && pack_request && process_response;
}
bool support_server() const { return process_request; }
};
parse:服务端和客户端都需要,用于后序的处理请求和响应
serialize_request:客户端需要,用于将Message序列化二进制,用于后序的PackRequest
pack_request:客户端需要,打包请求用于后面通过套接字发送出去
process_request:服务端需要,用于处理客户端发来Parse后的请求
process_response:客户端需要,用于处理服务端回的消息(经过Parse处理后的)
verify:用于授权服务器使用
parse_server_address:可选,将服务器地址及端口转成EndPoint
get_method_name:可选,自定义方法名
support_client:判断协议是否支持客户端
support_server:判断协议是否支持服务端
supported_connection_type:支持的连接类型
name:协议名
协议管理
协议是通过ProtocolMap来管理的,其定义为
struct ProtocolMap {
ProtocolEntry entries[MAX_PROTOCOL_SIZE];
};
struct ProtocolEntry {
butil::atomic<bool> valid;
Protocol protocol;
ProtocolEntry() : valid(false) {}
};
ProtocolMap 通过ProtocolEntry 类型数组来管理Protocol
在brpc中,GlobalInitializeOrDieImpl函数会注册所有的Protocol
GlobalInitializeOrDie函数会调用GlobalInitializeOrDieImpl
void GlobalInitializeOrDie() {
if (pthread_once(®ister_extensions_once,
GlobalInitializeOrDieImpl) != 0) {
LOG(FATAL) << "Fail to pthread_once";
exit(1);
}
}
在Channel::Init方法中会调用 GlobalInitializeOrDie