当前位置:网站首页>分布式网络通信框架:本地服务怎么发布成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
边栏推荐
- 苹果独占鳌头,三星大举复兴,国产手机在高端市场颗粒无收
- POJ 1012 Joseph
- Gauss elimination
- 在同一conda环境下先装Pytroch后装TensorFlow
- JS 连等赋值操作
- Interpretation of the standard of software programming level examination for teenagers_ second level
- 2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)
- Phpexcel export Emoji symbol error
- JS continuous assignment operation
- [fluorescent character effect]
猜你喜欢
![[datawhale] [machine learning] Diabetes genetic risk detection challenge](/img/98/7981af7948feb73168e5200b3dfac9.png)
[datawhale] [machine learning] Diabetes genetic risk detection challenge

服务器内存故障预测居然可以这样做!

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

R language ggplot2 visualization: align the legend title to the middle of the legend box in ggplot2 (default left alignment, align legend title to middle of legend)

MQTT X CLI 正式发布:强大易用的 MQTT 5.0 命令行工具

解决npm -v突然失效 无反应

Spolicy request case

CSV data file settings of JMeter configuration components

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

PMM (percona monitoring and management) installation record
随机推荐
Docker configuring MySQL Cluster
R语言ggplot2可视化: 将图例标题(legend title)对齐到ggplot2中图例框的中间(默认左对齐、align legend title to middle of legend)
服务发现原理分析与源码解读
挡不住了,纯国产PC已就位,美国的软硬件体系垄断正式被破
The diagram of user login verification process is well written!
A new paradigm of distributed deep learning programming: Global tensor
JS判断数据类型 Object.prototype.toString.call和typeof
R language ggplot2 visualization: align the legend title to the middle of the legend box in ggplot2 (default left alignment, align legend title to middle of legend)
系统安装Serv-U后IIS出错提示:HRESULT:0x80070020
“互联网+”时代的现代医学
Use of tabbarcontroller
[fluorescent character effect]
Mqtt x cli officially released: powerful and easy-to-use mqtt 5.0 command line tool
Antd treeselect gets the value of the parent node
IIS error prompt after installing Serv-U: hresult:0x80070020
【Datawhale】【机器学习】糖尿病遗传风险检测挑战赛
Table extraction for opencv table recognition (2)
Flutter Event 派发
Customize permission validation in blazor
Nodejs service background execution (forever)