[分布式网络通讯框架]----业务层代码

user.proto

syntax="proto3";

package fixbug;

option cc_generic_services=true;

message ResultCode
{
    int32 errcode=1;
    bytes errmsg=2;
}

message LoginRequest
{
    bytes name=1;
    bytes pwd=2;
}

message LoginResponse
{
    ResultCode result=1;
    bool success =2;
}

message RegisterRequest
{
    uint32 id=1;
    bytes name=2;
    bytes pwd=3;
}

message RegisterResponse
{
    ResultCode result=1;
    bool success =2;
}

service UserServiceRpc
{
    rpc Login(LoginRequest) returns(LoginResponse);
    rpc Register(RegisterRequest) returns(RegisterResponse);
}
  • 正如上一节所讲的,我们使用protoc user.proto -I ./ -cpp_out=./user命令来得到对应的user.pb.h以及user.pb.cc文件。
  • user.cc和user.h里面提供了两个非常重要的类供c++程序使用,
  • UserServiceRpc_Stub类给caller使用,可以调用UserServiceRpc_Stub::Login(...)发起远端调用
  • UserServiceRpccallee使用。callee则继承UserServiceRpc类并重写UserServiceRpc::Login(...)函数,实现Login函数的处理逻辑。
  • user.proto中也注册了通信的消息体(LoginRequest、LoginResponse、RegisterRequest、RegisterResponse(其中嵌套了ResultCode)),这些注册的消息体也会由protoc生成对应的C++类和业务代码进行交互。

userservice.cc

#include <iostream>
#include <string>
#include "user.pb.h"
#include "rpcprovider.h"
#include "mprpcapplication.h"

class UserService : public fixbug::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 true;
    }

    bool Register(uint32_t id,std::string name,std::string pwd)
    {
        std::cout<<"doing local service:Register"<<std::endl;
        std::cout<<"id: "<<id<<"name: "<<name<<" pwd: "<<pwd<<std::endl;
        return true;
    }

    void Login(::google::protobuf::RpcController *controller,
                       const ::fixbug::LoginRequest *request,
                       ::fixbug::LoginResponse *response,
                       ::google::protobuf::Closure *done)
    {
        //框架给业务上报了请求参数LoginRequest,应用获取相应数据做本地业务
        std::string name=request->name();
        std::string pwd=request->pwd();

        //做本地业务
        bool login_result=Login(name,pwd); 

        //把响应写入
        fixbug::ResultCode *code=response->mutable_result();
        code->set_errcode(0);
        code->set_errmsg("");

        response->set_success(login_result);

        done->Run();
    }

    void Register(::google::protobuf::RpcController *controller,
                  const ::fixbug::RegisterRequest *request,
                  ::fixbug::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();

    }
};
  • Userservice在不继承UserServiceRpc类的时候,它是一个本地服务,提供了两个进程内的本地方法,Login和GetFriendLists。
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 true;
}

bool Register(uint32_t id,std::string name,std::string pwd)
{
    std::cout<<"doing local service:Register"<<std::endl;
    std::cout<<"id: "<<id<<"name: "<<name<<" pwd: "<<pwd<<std::endl;
    return true;
}
  • 继承UserServiceRpc类,即class UserService : public fixbug::UserServiceRpc之后,我们将它实现为了rpc服务发布端,也就是rpc服务的提供者。
  • 重写基类UserServiceRpc的虚函数caller = = > Login(LoginRequest) = => muduo = => callee = => Login(LoginRequest) = => 交到重写Login以及Register方法。
  • 在Login以及Register方法中,主要实现框架给业务上报了请求参数LoginRequest,我们通过request底层相关方法可以使应用获取相应数据做本地业务Login(name,pwd); ;然后写入相关的响应,执行回调操作,即执行响应对象的序列化和网络发送(这都是由框架来完成的)

main函数

int main(int argc,char **argv)
{
    //调用框架初始化操作
    MprpcApplication::Init(argc,argv);

    RpcProvider provider;
    provider.NotifyService(new UserService());

    //启动一个rpc服务发布节点
    provider.Run();

    return 0;
}
  • 在main函数中,首先调用框架初始化操作,这在MprpcApplication中会分析到;
  • 创建RpcProvider 对象,调用NotifyService方法,这是框架提供给外部使用的,可以发布rpc方法的函数接口,可以接受任意的service。void NotifyService(google::protobuf::Service *service);RpcProvider中会分析到;
  • 启动rpc服务节点,开始提供rpc远程网络调用服务,Run以后,进程进入阻塞状态,等待远程的rpc调用请求.

calluserservice.cc

#include <iostream>
#include "mprpcapplication.h"
#include "user.pb.h"
#include "mprpcchannel.h"


int main(int argc,char **argv)
{
    MprpcApplication::Init(argc,argv);

    //演示调用远程发布的rpc方法的Login
    fixbug::UserServiceRpc_Stub stub(new MprpcChannel());

    //rpc方法的请求参数
    fixbug::LoginRequest request;
    request.set_name("zhang san");
    request.set_pwd("123456");

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

    MprpcController controller;
    stub.Login(&controller,&request,&response,nullptr);

    //一次rpc调用完成,读调用的结果
    if (controller.Failed())
    {
        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;
        }
    }
        
    MprpcController controller1;
    if (controller.Failed())
    {
        std::cout << controller.ErrorText() << std::endl;
    }
    else
    {
        //演示调用远程发布的rpc方法的Register
        fixbug::RegisterRequest req;
        req.set_id(200);
        req.set_name("mprpc");
        req.set_pwd("6666");
        fixbug::RegisterResponse rsp;
        stub.Register(&controller1,&req,&rsp,nullptr);

        if(0==rsp.result().errcode())
        {
            std::cout<<"Register login response success: "<<
                rsp.success()<<std::endl;
        }
        else
        {
            std::cout<<"Register login response error: "<<
                rsp.result().errmsg()<<std::endl;
        }
    }
    
    return 0;
}
  • 首先,callee在发起远程调用时,要先进行初始化,在MprpcApplication类中提供了解析argc和argv参数的方法,我们在终端执行这个程序的时候,需要通过-i参数给程序提供一个配置文件,这个配置文件里面包含了ip以及port
  • 实例化了一个UserServiceRpc_Stub对象,这个是我们在上一节提到的.proto中产生的最终的两个类其中之一,底层实际是通过继承google::protobuf::RpcChannel实现了一个channel类,可以通过这个类解析到调用端需要的服务,然后通过网络进行服务实现。
  • 接下来,通过LoginRequest,RegisterRequest给入rpc方法需要的参数,以及相应的响应类,对应的也是我们在.proto中给的rpc Login(LoginRequest) returns(LoginResponse);
  • 将给入UserServiceRpc_Stub类,得到我们想要的响应结果。这个类第一个参数还需要一个controller值,这个我们将在后面提到。
  • 0==rsp.result().errcode()通过返回的错误码,我们可以判断响应结果是否是我们想要的。
  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值