一、引言
分布式的布置决定了业务的不同功能可能放在不同的主机中。当一台主机A需要调用另一台主机B的方法时,则需要主机B提前将自己的本地服务发布成RPC服务。
在这个过程中,主要需要做两件事:
- 主机A应该怎么调用这个接口(给出接口的使用方式)
- 主机B在接口里面具体实现了什么
二、具体实现
1. 主机A应该怎么调用这个接口(给出接口的使用方式)
首先需要主机B来创建一个 user.proto
文件来注册本地业务的RPC方法:
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;
}
// 注册RPC方法
service UserServiceRpc {
rpc Login(LoginRequest) returns(LoginResponse);
}
这里最关键的就是最后一段代码,它注册一个RPC方法:如果想调用我的登录方法,你就使用函数Login,参数是LoginRequest。返回是一个LoginResponse
。
在定义RPC服务的名称以及函数接口(函数名字+参数类型)、返回类型之后。使用指令:
protoc user.proto --cpp_out ./
转化为C++类型的头文件 "user.pb.h"
,就可以拿来使用了。
三、主机B具体实现接口里面的内容
在注册了方法之后。主机B需要具体实现接口里面的内容:
#include <iostream>
#include <string>
#include "user.pb.h"
fixbug::ResultCode*
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 << endl;
return true;
}
void Login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done)
{
// 本地重写业务
std::string name = request->name();
std::string pwd = request->pwd();
bool loginResult = Login(name, pwd); // 做本地业务
// 把响应写入
response->set_success(loginResult);
fixbug::ResultCode *code = response->mutable_result();
code->set_errcode(0);
code->set_errmsg("");
// 执行回调 执行响应对象的序列化和网络发送,由框架完成
done->Run();
}
}
这里的具体实现是主机B继承了UserServiceRpc
来实现接口里面的内容。第一个Login
其实就是本地的方法,第二个带有很多参数调用了本地的来真正执行本地的操作。里面的参数其实就是RPC框架在网络中接收到的参数。