RpcController作用浅析
前面提到了RpcConsumer的实现思路,但是并没说明RpcController有什么作用,不妨看看google::protobuf::RpcController:
class PROTOBUF_EXPORT RpcController {public:inline RpcController() {}virtual ~RpcController();// Client-side methods ---------------------------------------------// These calls may be made from the client side only. Their results// are undefined on the server side (may crash).// Resets the RpcController to its initial state so that it may be reused in// a new call. Must not be called while an RPC is in progress.virtual void Reset() = 0;// After a call has finished, returns true if the call failed. The possible// reasons for failure depend on the RPC implementation. Failed() must not// be called before a call has finished. If Failed() returns true, the// contents of the response message are undefined.virtual bool Failed() const = 0;// If Failed() is true, returns a human-readable description of the error.virtual std::string ErrorText() const = 0;// Advises the RPC system that the caller desires that the RPC call be// canceled. The RPC system may cancel it immediately, may wait awhile and// then cancel it, or may not even cancel the call at all. If the call is// canceled, the "done" callback will still be called and the RpcController// will indicate that the call failed at that time.virtual void StartCancel() = 0;// Server-side methods ---------------------------------------------// These calls may be made from the server side only. Their results// are undefined on the client side (may crash).// Causes Failed() to return true on the client side. "reason" will be// incorporated into the message returned by ErrorText(). If you find// you need to return machine-readable information about failures, you// should incorporate it into your response protocol buffer and should// NOT call SetFailed().virtual void SetFailed(const std::string& reason) = 0;// If true, indicates that the client canceled the RPC, so the server may// as well give up on replying to it. The server should still call the// final "done" callback.virtual bool IsCanceled() const = 0;// Asks that the given callback be called when the RPC is canceled. The// callback will always be called exactly once. If the RPC completes without// being canceled, the callback will be called after completion. If the RPC// has already been canceled when NotifyOnCancel() is called, the callback// will be called immediately.//// NotifyOnCancel() must be called no more than once per request.virtual void NotifyOnCancel(Closure* callback) = 0;private:GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RpcController);
};
可以看到RpcController是一个抽象类,里面有一些纯虚函数,
Reset()表示rpc状态、
Failed()表示rpc请求过程中是否发生了错误,
ErrorText()表示如果rpc请求出错了,那么错误的原因是什么
SetFailed()表示rpc请求出错了,需要设置错误的原因
StartCancel()、IsCanceled()、NotifyOnCancel()表示是否取消rpc以及相应的回调。
显然这个类的作用可以很好的帮助rpcClient判断rpc请求过程中是否出错、错误原因、或是什么原因rpcServer取消了。
否则没有Rpccontroller的帮助,RpcClient调用rpc请求之后等待rpcServer的响应,然后反序列化响应。但如果中间错误了,那么RpcClient本地序列化response响应肯定会不成功(没必要序列化响应), 也不知道具体原因是什么,这就很不友好了。那么有了RpcController可以很轻松的解决这种问题。
老样子,实现RpcController很简单,写一个派生类继承自google::protobuf::RpcController,并重写需要提供给用户的方法。
这里提供一个简单版本MyRpcController类:
#pragma once
#include <google/protobuf/service.h>
#include <string>class MyRpcController : public google::protobuf::RpcController
{
public:MyRpcController ();void Reset();bool Failed() const;std::string ErrorText() const;void SetFailed(const std::string& reason);//目前未实现具体的功能void StartCancel();bool IsCanceled() const;void NotifyOnCancel(google::protobuf::Closure* callback);private:bool m_failed; //RPC方法执行过程中的状态std::string m_errText; //Rpc方法执行过程中的错误信息
};//.cc
#include "myrpccontroller.h"MyRpcController ::MyRpcController ()
{m_failed = false;m_errText = "";
}void MyRpcController ::Reset()
{m_failed = false;m_errText = "";
}bool MyRpcController ::Failed() const
{return m_failed;
}std::string MyRpcController ::ErrorText() const
{return m_errText;
}void MyRpcController ::SetFailed(const std::string& reason)
{m_failed = true;m_errText = reason;
}//目前未实现具体的功能
void MyRpcController ::StartCancel(){}bool MyRpcController ::IsCanceled() const{return false;}void MyRpcController ::NotifyOnCancel(google::protobuf::Closure* callback){}
使用MyRpcController
fixbug::UserServiceRpc_Stub stub(new MyRpcChannel());MyRpcController controllerLogin; //rpcController//rpc方法的请求参数fixbug::LoginRequest request;request.set_name("zhang san");request.set_pwd("123");//rpc方法的响应,同步的rpc调用过程fixbug::LoginResponse response;stub.Login(&controllerLogin, &request, &response, nullptr);//一次rpc调用完成,读调用的结果if(!controllerLogin.Failed() && 0 == response.result().errcode()){std::cout << "rpc login response success: " << response.success() << std::endl;}else{if(controllerLogin.Failed())std::cout<<controllerLogin.ErrorText()<<std::endl;else std::cout << "rpc login error msg : " << response.result().errmsg() << std::endl;}
至此,简单的RpcController实现。