RPC Service提供者callee文件夹/RPC Service调用者caller文件夹/RPC Service生成方proto文件


example文件夹作为我们框架项目的使用实例,在example文件夹下创建callee和caller两个文件夹,还包含用于生成rpc service的proto文件。

proto文件

在proto文件中我们使用了message和service两个关键词组,在编译proto文件时会将他们对应的内容都生成为相应的类,例如:UserService原来是一个本地服务,提供了进程内的本地方法:Login(),在proto文件中需要先在service类UserServiceRpc中注册Login()方法。然后对proto文件进行编译生成后会生成对应的.pb.h和.pb.cc文件,其中会将proto文件注册的service直接生成为对应的类。

syntax ="proto3";

package RPC;

option cc_generic_services=true;

//失败类
message ResultCode
{
    int32 errcode=1;//错误代码
    bytes errmsg=2;//错误消息
}

//登陆request
message LoginRequest
{
    bytes name=1;//姓名
    bytes pwd=2;//密码
}

//登陆response
message LoginResponse
{
    ResultCode result=1;//失败类
    bool success=2;//判断rpc执行成功还是执行失败
}

//注册request
message RegisterRequest
{
    uint32 id=1;//账号
    bytes name=2;//用户名
    bytes pwd=3;//密码
}

//注册response
message RegisterResponse
{
    ResultCode result=1;//失败类
    bool success=2;//判断rpc执行成功还是执行失败
}

//用户模块的rpc service,里面包含两个rpc method
service UserServiceRpc
{
    rpc Login(LoginRequest)returns(LoginResponse);
    rpc Register(RegisterRequest)returns(RegisterResponse);
}

在这里插入图片描述可以看到service已经生成了类,而他对应的Login()方法也已经生成了虚函数(生成虚函数的作用下边再说)。

callee文件夹

这个文件夹包含不同的rpc service文件,每个文件将不同的本地服务发布成rpc service。

//本地服务发布成RPC服务的方法

#include <iostream>
#include <string>

#include "../user.pb.h" //包含protobuf头文件
#include "mprpcapplication.h"
#include "mprpcprovider.h"

//using namespace RPC;
	/*我的角色是服务的提供者,你作为远端想发起一个调用我这个机器上的UserService的Login方法
	首先你会发一个RPC请求,这个请求是先到RPC框架,RPC框架根据你发过来的请求,然后根据参数和标识
	匹配到我的Login方法,然后它就把这个网络上发的请求上报来,我接收到这个请求后,从请求中拿取数据,
	然后做本地业务,填写相应的响应,然后再执行一个回调,相当于把执行完的这个RPC方法的返回值再塞给框架
	,然后框架再进行序列化,通过网络传送回去,发送给你。体现在Login的四个参数。
	*/

//RPC::UserServiceRpc有Login()和Register()的虚函数,UserService是一个本地类,需要重写这两个函数,以便于UserServiceRpc::CallMethod()调用
class UserService : public RPC::UserServiceRpc
{
public:
    //登入系统的本地方法
    bool Login(std::string name, std::string pwd)
    {
        std::cout << "doing local service:Login" << std::endl;
        std::cout << "name:" << name << " pwd:" << pwd << std::endl;
        return false;
    }

    //新增注册的本地方法
    bool Register(uint32_t id, std::string name, std::string pwd)
    {
        std::cout << "doing Register service:Login" << std::endl;
        std::cout << "id:" << id << " name:" << name << " pwd:" << pwd << std::endl;
        return true;
    }

    /*
    重写基类UserServiceRpc的 Login()和Register()虚函数,以下方法由UserServiceRpc::CallMethod()直接调用
    1.caller远程调用者发起远程调用请求Login(LoginRequest)=>muduo=>callee
    2.callee发现远程请求调用Login(LoginRequest)=>调用UserServiceRpc::CallMethod()=>调用下面的rpc method

    各个参数的作用:
    1.从LoginRequest获取参数的值
    2.执行本地服务Login,并获取返回值
    3.用上面的返回值填写LoginResponse
    4.一个回调,把LoginResonse发送给发起RPC服务的主机
    */
    void Login(::google::protobuf::RpcController *controller,
               const ::RPC::LoginRequest *request,
               ::RPC::LoginResponse *response,
               ::google::protobuf::Closure *done)
    {
        //框架给业务上报了请求参数:LoginRequest,应用程序取出request中相应的已反序列化的数据来做本地业务
        std::string name = request->name();
        std::string pwd = request->pwd();

        调用本地方法,实现rpc
        bool loginresult = Login(name, pwd);

        //把response写入,包括错误码,错误信息和运行结果
        RPC::ResultCode *Code = response->mutable_result();
        Code->set_errcode(0);
        Code->set_errmsg("");
        response->set_success(loginresult);

        //执行回调函数RpcProvider::SendRpcResponse()
        done->Run();
    }

    void Register(::google::protobuf::RpcController *controller,
                  const ::RPC::RegisterRequest *request,
                  ::RPC::RegisterResponse *response,
                  ::google::protobuf::Closure *done)
    {
        uint32_t id = request->id();
        std::string name = request->name();
        std::string pwd = request->pwd();

        //开始做本地业务
        bool ret = Register(id, name, pwd);

        //填充回调结果
        response->mutable_result()->set_errcode(0);
        response->mutable_result()->set_errmsg("");
        response->set_success(ret);

        done->Run();
    }
};

int main(int argc, char **argv)
{
    //先调用框架的初始化操作 provider -i config.conf,从init方法读取配置服务,比如IP地址和端口号
    MprpcApplication::Init(argc, argv);

    //通过RpcProvider把UserService对象发布到rpc节点上
    RpcProvider provider;
    provider.NotifyService(new UserService()); //发布service

    //启动一个rpc服务发布节点,Run以后,进程进入阻塞状态,等待远程的rpc请求
    provider.Run();

    return 0;
}

caller文件夹

caller文件夹下的文件使用callee发布的rpc service,调用rpc service里的rpc method。

//caller就是按照rpc服务方(callee)提供的proto协议,发起调用
#include "mprpcapplication.h"
#include "mprpcchannel.h"
#include "user.pb.h"
#include <iostream>

int main(int argc, char **argv)
{
    //整个程序启动以后,想使用mprpc来获取rpc服务调用,一定需要先调用框架的初始化函数(只初始化一次)
    MprpcApplication::Init(argc, argv);

    //创建与所要使用的rpc相对应的service类对象
    RPC::UserServiceRpc_Stub stub(new MprpcChannel);

    //rpc方法的请求参数
    RPC::LoginRequest request;
    request.set_name("zhangsan");
    request.set_pwd("123");

    //rpc方法的响应
    RPC::LoginResponse response;

    //stub.Login()调用channel_->CallMethod(descriptor()->method(0),controller, request, response, done)发送request到服务器端,并填充response
    MprpcController controller;
    stub.Login(&controller, &request, &response, nullptr);

    //读取一次rpc调用完成后的response
    if (controller.Failed()) //RPC调用过程中出现错误了
    {
        std::cout << controller.ErrorText() << std::endl;
    }
    else
    {
        if (0 == response.result().errcode())
        {
            std::cout << "rpc Login response success : " << response.success() << std::endl;
        }
        else
        {
            std::cout << "rpc Login response error : " << response.result().errmsg() << std::endl;
        }
    }

    //调用远程发布的rpc方法Register
    RPC::RegisterRequest req;
    req.set_id(2001);
    req.set_name("linZY");
    req.set_pwd("666666");
    RPC::RegisterResponse rsp;

    //以同步的方式发起rpc调用请求,等待返回结果
    MprpcController controller1;
    stub.Register(&controller1, &req, &rsp, nullptr);

    //一次rpc调用完成,读调用的结果
    if (controller1.Failed()) //RPC调用过程中出现错误了
    {
        std::cout << controller1.ErrorText() << std::endl;
    }
    else
    {
        if (0 == rsp.result().errcode())
        {
            std::cout << "rpc register response success:" << rsp.success() << std::endl;
        }
        else
        {
            std::cout << "rpc register response error : " << rsp.result().errmsg() << std::endl;
        }
    }

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值