proto文件:请求、回复、服务的接口都定义在proto文件中,且方法都是虚函数。
option cc_generic_service= true:标志生成c++类(java/py_generic_service)。
import引入包,pack跟namespace差不多可以对类进行打包。
proto文件生成后的类,需要写impl类继承proto.class(proto文件生成的类),实现它的虚函数:
class MyImpl : public ProtoClass
{
public:
void Method(::google::protobuf::RpcController* cntl_base,
const ::example::Request* request,
::example::Response* response,
::google::protobuf::Closure* done)
{
//RAII,确保调用done->Run()
brpc::ClosureGuard done_guard(done);
brpc::Controller* cntl= static_cast<brpc::Controller*>(cntl_base);
//fill response
response->set_message(/*data*/);
}
};
HTTP 可通过URL类型访问:
前缀为 /ServiceName/MehtodName:制定特定MethodName
前缀为 /ServiceName:实现默认虚函数default_method
HTTP 可通过Restful URL访问:
brpc支持为service中的每个方法指定一个URL:butil::StringPiece
映射规则:多个路径可以映射至同一个方法、service不要求纯HTTP,pb service也支持、没有出现的映射中的方法仍然通过/ServiceName/MethodName访问,出现映射则不可以、一个路径只能出现一个*号
controller:在brpc中可以静态转为brpc::Controller(包含除了reques和response以外的参数集):
客户端methods包括:
set_timeout_ms(int64_t);RPC call
set_backup_request_ms(int64_t);delay to send backup request
response(); response of the RPC call(passed to CallMethod)
http_request(); mutable header of http request
set_log_id(uint64_t);an identifier to send to server along with request
set_type_of_service(short tos);必须在连接前设置,连接后设置是没有影响的
set_connection_type(ConnectionType);set type of connections for sending RPC
set_request_compress_type(CompressType);set compression method for request
butil::IOBuf& request_attachment();user atached data or body of htp request,while is wired to network directly instread of begin serialized into protobuf message.
method();get the called method,may-be NULL for non-pb services.
服务器端methods包括:
IsCanceled();客户端取消RPC或者链接中断,返回true。服务端应该放弃回复它,然后回调done
NotityOnCancel();当RPC取消或者链接中断调用回调(只能调用一次)
auth_context();返回一个authenticated结果,null 表示没有 啊uthentication
http_response();mutable header of http response
butil::IOBuf& response_attachment();user attached data or body of http response,which is wired to network directly inseted of being serialized into protobuf messages
CreateProgressiveAttachment();Crate a ProgressiveAttachment to write(often after RPC)
trace_id()/span_id();Non-zero when this Rpc call is traced(by rpcz or rig)
CloseConnection();tell RPC to close the connection(the underlying connection is not closed immediately) instead of sending back response.
is_security_mode();the RPC is from connections accepted from port
session_local_data();Get the data attached to current RPC session
客户端与服务端同有methods:
remote_side();
local_side();
is_ssl();
Reset();resets the controller to its initial state so that it my be reused in a new call
SetFauked(); reason will be incorporated into the message returned by ErrorText()
Failed(); after a call has finished,returns true if the RPC call failed.
ErrorText();if Failed() is true,return description of the errors
request/response_compress_type();
http_request();如果为NULL则返回默认http header
http_response();
request_attachment();
response_attachment();
has_remote_stream();return true if the remote side creates a stream.
request:请求,只读的,来自客户端的数据包
response:回复,需要用户填充,如果存在required字段没有被设置,该次调用会失败
done:done由框架创建,递给服务回调,包含了调用服务回调后的后续动作,包括检查response正确性、序列化、打包、发送等逻辑(done由用户自己调用而不是框架(ClosureGuard调用done->Run),这允许用户把done保存下来,在服务回调之后的某事件发生时再调用,即异步Service,异步为了避免正常脱离函数时done->Run也被调用,可以在结束尾调用done_guard.release()来释放其中done)
服务端的done的逻辑主要是:
发送response会客户端,当其发现用户调用lSetFailed()后,会把错误信息发送会客户端,客户端接收到,它的Controller::Failed()会返回 true,Controller::ErrorCode()和Controller::ErrorText()则分别是错误码和错误信息
服务端的异步服务:
即done->Run()在Service回调之外被调用。有些server以等待后端服务返回结果为主,且处理时间特别长,为了及时地释放出线程资源,更好的办法是把done注册到被等待事件的回调中,等待事件发生后再调用done->Run(),异步service的最后一行一般是done_guard.release()以确保正常退出CallMethod时不会被调用done->Run()。
service的done由框架创建,用户处理请求后调用done把response发回给客户端
channel的done由用户创建,待RPC结束后被框架调用以执行用户的后续代码。
Protobuf的服务通常可以通过HTTP+json访问,存在http body的json可与对于protobuf消息互相转化,json字段通过匹配的名字和结构与pb字段一一对应。json中一定要包含pb的required字段,否则转化会失败对应请求会被拒绝。json中可以包含pb中没有定义的字段,但它们会被丢弃而不会存入pb的unknown字段(原因在于protobuf真正的key是proto文件中的每个字段后的数字)。