当前位置:网站首页>分布式网络通信框架:本地服务怎么发布成RPC服务
分布式网络通信框架:本地服务怎么发布成RPC服务
2022-07-26 09:50:00 【_索伦】
1. 编写protobuf配置文件确定需求
想把本地服务发布成rpc服务,第一点就是利用protobuf,生成对应得Service服务类。
以登录业务为例:
最下面编写的就是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;
}
service UserServiceRpc
{
rpc Login(LoginRequest) returns(LoginResponse);
}
2. 继承相对应的类并重写虚方法
编写完配置文件,生成C++对应的头文件与源文件,里面就会生成 上面的配置文件约定的类(这里就是 UserServiceRpc),里面有对应的方法。
class UserServiceRpc : public ::PROTOBUF_NAMESPACE_ID::Service {
protected:
// This class should be treated as an abstract interface.
inline UserServiceRpc() {
};
public:
virtual ~UserServiceRpc();
typedef UserServiceRpc_Stub Stub;
static const ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor* descriptor();
virtual void Login(::PROTOBUF_NAMESPACE_ID::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done);
// implements Service ----------------------------------------------
// 省略。。。
那么在我本地编写业务时,首先要继承该类,并需要重写该类的Login方法
class UserService : public fixbug::UserServiceRpc // 使用在rpc服务发布端
{
public:
bool Login(std::string name, std::string pwd)
{
std::cout << "doing local service: Login " << std::endl;
std::cout << "name: " << name << "pwd: " << name << std::endl;
return true;
}
// 重写基类UserServiceRpc的虚函数,这些方法都是框架直接调用的
virtual void Login(::google::protobuf::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done)
{
}
};
3. 业务实现
首先要了解的是调用过程:
如下图所示,caller调用者把这个方法的请求发送到网络,由muduo库来处理,交给了callee提供者,提供者得知这个请求后,去找到这个方法,这个方法就是我们业务上重写的虚方法。

virtual void Login(::google::protobuf::RpcController* controller,
const ::fixbug::LoginRequest* request,
::fixbug::LoginResponse* response,
::google::protobuf::Closure* done);
那么对于这样一个Login()方法,需要理解这些参数对我们的帮助:
首先controller指针,这里先不用管他的作用
request:框架给业务上报了请求参数LoginRequest,应用可以获取相应数据做本地业务

那么可以很方便的到请求数据:
std::string name = request->name();
std::string pwd = request->pwd();
然后就可以做本地业务,这里就调用本地的Login()方法
// 做本地业务
bool login_result = Login(name, pwd);
调用的这个::
然后把响应消息写入参数response中:
这个LoginResponse和上面的LoginRequest请求也是对应的:

为什么会是在mutable_result()里填写,这个在上一篇文章中【protobuf使用】里有提到。
// 把响应写入 (错误码,错误消息,返回值)
fixbug::ResultCode* code = response->mutable_result();
code->set_errcode(0);
code->set_errmsg("");
response->set_success(login_result);
最后执行回调操作,执行响应对象数据的序列化和网络发送。
protobuf为我们提供了该参数done,该类型是Closure

// 执行回调操作
done->Run();
完整代码:
#include <iostream>
#include <string>
#include "user.pb.h"
/* UserService原本是一个本地服务,提供两个进程内的本地方法,Login和GetFriendLists */
class UserService : public fixbug::UserServiceRpc // 使用在rpc服务发布端
{
public:
bool Login(std::string name, std::string pwd)
{
std::cout << "doing local service: Login " << std::endl;
std::cout << "name: " << name << "pwd: " << name << std::endl;
return true;
}
// 重写基类UserServiceRpc的虚函数,这些方法都是框架直接调用的
// 1. caller ==> Login(LoginRequest) ==> muduo ==> callee
// 2. callee ==> Login(LoginRequest) ==> 交到重写的这个方法上
virtual 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();
}
};
end
边栏推荐
- regular expression
- Add DLL
- JS 连等赋值操作
- POJ 1012 Joseph
- copyTo
- The whole process of server environment configuration
- Apple dominates, Samsung revives, and domestic mobile phones fail in the high-end market
- Sublime install plug-ins
- 2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)
- 编写一个在bash / shell 和 PowerShell中均可运行的脚本
猜你喜欢

SSG框架Gatsby访问数据库,并显示到页面上

【Datawhale】【机器学习】糖尿病遗传风险检测挑战赛

Spolicy request case

Apple dominates, Samsung revives, and domestic mobile phones fail in the high-end market

小白搞一波深拷贝 浅拷贝

2021年山东省中职组“网络空间安全”B模块windows渗透(解析)

Gauss elimination solves the inverse of matrix (Gauss)

2019 ICPC Asia Yinchuan regional (water problem solution)

高斯消元求解矩阵的逆(gauss)

B站这个视频我是跪着看完的
随机推荐
2019 ICPC Asia Yinchuan Regional(水题题解)
“互联网+”时代的现代医学
Xiaobai makes a wave of deep copy and shallow copy
Alibaba cloud technology expert haochendong: cloud observability - problem discovery and positioning practice
JS continuous assignment operation
Double authentication of server and client
学习笔记之常用数组api 改变原数组和不改变原数组的有哪些?
网络流学习笔记
Calling DLL to start thread
高斯消元
Logical architecture of MySQL
AR model in MATLAB for short-term traffic flow prediction
Sqoop [environment setup 01] CentOS Linux release 7.5 installation configuration sqoop-1.4.7 resolve warnings and verify (attach sqoop 1 + sqoop 2 Latest installation package +mysql driver package res
(2) Hand eye calibration of face scanner and manipulator (eye out of hand: nine point calibration)
阿里云技术专家郝晨栋:云上可观测能力——问题的发现与定位实践
高斯消元求解异或线性方程组
Nodejs service background execution (forever)
Use of selectors
Gauss elimination solves the inverse of matrix (Gauss)
PHP one-time request lifecycle