RpcController作用浅析

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实现。

你可能感兴趣的:(分布式,分布式,rpc,c++)