【链接】GitHub - qicosmos/rest_rpc: modern C++(C++11), simple, easy to use rpc framework
rpc_client
是一个用于实现远程过程调用(Remote Procedure Call, RPC)的客户端类。利用 Asio 库进行网络通信,并支持异步操作、SSL 安全连接(如果启用)、超时控制等功能。这个类允许客户端以不同的方式初始化,并提供了灵活的消息处理机制。
核心功能
- 异步网络通信:使用 Asio 提供的异步 I/O 操作来执行非阻塞网络请求。
- SSL 支持:在定义了
CINATRA_ENABLE_SSL
的情况下,可以支持安全的 SSL/TLS 连接。 - 超时管理:通过
asio::steady_timer
实现超时控制,确保在网络异常时能够及时响应。 - 消息队列与缓冲区:维护待发送消息的队列和接收响应数据的缓冲区,保证数据的有序处理。
- 回调机制:通过设置回调函数来处理来自服务器的响应或错误情况。
- 重连机制:提供重连尝试次数配置,增强连接稳定性。
成员变量解析
这个类包含了许多成员变量,用于管理RPC客户端的状态和操作。
asio::io_context ios_;
asio::ip::tcp::socket socket_;
#ifdef CINATRA_ENABLE_SSL
std::unique_ptr<asio::ssl::stream<asio::ip::tcp::socket &>> ssl_stream_;
std::function<void(asio::ssl::context &)> ssl_context_callback_;
#endif
std::shared_ptr<asio::io_context::work> work_;
std::shared_ptr<std::thread> thd_ = nullptr;
std::string host_;
unsigned short port_ = 0;
size_t connect_timeout_ = 1000; // s
int reconnect_cnt_ = -1;
std::atomic_bool has_connected_ = {false};
std::mutex conn_mtx_;
std::condition_variable conn_cond_;
bool has_wait_ = false;
asio::steady_timer deadline_;
bool stop_client_ = false;
struct client_message_type {
std::uint64_t req_id;
request_type req_type;
string_view content;
uint32_t func_id;
};
std::deque<client_message_type> outbox_;
uint32_t write_size_ = 0;
std::mutex write_mtx_;
uint64_t fu_id_ = 0;
std::function<void(asio::error_code)> err_cb_;
bool enable_reconnect_ = false;
std::unordered_map<std::uint64_t, std::shared_ptr<std::promise<req_result>>>
future_map_;
std::unordered_map<std::uint64_t, std::shared_ptr<call_t>> callback_map_;
std::mutex cb_mtx_;
uint64_t callback_id_ = 0;
uint64_t temp_req_id_ = 0;
char head_[HEAD_LEN] = {};
std::vector<char> body_;
rpc_header header_;
std::unordered_map<std::string, std::function<void(string_view)>> sub_map_;
std::set<std::pair<std::string, std::string>> key_token_set_;
client_language_t client_language_ = client_language_t::CPP;
std::function<void(long, const std::string &)> on_result_received_callback_;
1. ASIO网络相关变量
asio::io_context ios_; // IO服务上下文
asio::ip::tcp::socket socket_; // TCP套接字
#ifdef CINATRA_ENABLE_SSL
std::unique_ptr<asio::ssl::stream<asio::ip::tcp::socket &>> ssl_stream_; // SSL流
std::function<void(asio::ssl::context &)> ssl_context_callback_; // SSL配置回调
#endif
std::shared_ptr<asio::io_context::work> work_; // 保持io_context运行的work对象
std::shared_ptr<std::thread> thd_ = nullptr; // 运行io_context的线程
asio::steady_timer deadline_; // 用于超时控制的定时器
作用:
-
管理所有网络异步操作的核心组件
-
支持普通TCP和SSL/TLS两种连接方式
-
独立线程处理IO事件
2. 连接管理变量
std::string host_; // 服务器主机地址
unsigned short port_ = 0; // 服务器端口
size_t connect_timeout_ = 1000; // 连接超时时间(毫秒)
int reconnect_cnt_ = -1; // 重连次数(-1表示无限重连)
std::atomic_bool has_connected_ = {false}; // 连接状态标志(原子变量)
std::mutex conn_mtx_; // 连接状态互斥锁
std::condition_variable conn_cond_; // 连接状态条件变量
bool has_wait_ = false; // 是否有线程在等待连接
bool stop_client_ = false; // 客户端停止标志
bool enable_reconnect_ = false; // 是否启用自动重连
作用:
-
存储服务器地址和连接参数
-
管理连接状态和重连逻辑
-
提供线程安全的连接状态通知机制
3. 消息处理变量
struct client_message_type {
std::uint64_t req_id; // 请求ID
request_type req_type; // 请求类型
string_view content; // 消息内容
uint32_t func_id; // 函数ID(MD5哈希)
};
std::deque<client_message_type> outbox_; // 待发送消息队列
uint32_t write_size_ = 0; // 当前正在写入的消息大小
std::mutex write_mtx_; // 写操作互斥锁
char head_[HEAD_LEN] = {}; // 消息头缓冲区
std::vector<char> body_; // 消息体缓冲区
rpc_header header_; // RPC消息头结构
作用:
-
管理待发送的消息队列
-
提供消息缓冲区和解析支持
-
确保消息有序发送(通过队列和互斥锁)
4. 请求响应管理变量
uint64_t fu_id_ = 0; // 请求ID计数器
std::unordered_map<std::uint64_t, std::shared_ptr<std::promise<req_result>>> future_map_; // Future映射表
std::unordered_map<std::uint64_t, std::shared_ptr<call_t>> callback_map_; // 回调映射表
std::mutex cb_mtx_; // 回调/Future映射表互斥锁
uint64_t callback_id_ = 0; // 回调ID计数器
uint64_t temp_req_id_ = 0; // 临时请求ID存储
作用:
-
为每个请求生成唯一ID
-
跟踪异步请求的future和callback
-
提供线程安全的请求-响应映射管理
5. 发布-订阅相关变量
std::unordered_map<std::string, std::function<void(string_view)>> sub_map_; // 订阅回调映射
std::set<std::pair<std::string, std::string>> key_token_set_; // 已订阅的主题-token集合
作用:
-
管理主题订阅和对应的回调函数
-
记录已订阅的主题用于自动重连后重新订阅
6. 多语言支持变量
client_language_t client_language_ = client_language_t::CPP; // 客户端语言类型
std::function<void(long, const std::string &)> on_result_received_callback_; // 结果接收回调
作用:
-
标识客户端语言类型(CPP/JAVA)
-
为Java等语言提供特殊的结果回调处理
构造函数解析
这段代码展示了rpc_client
类的四个构造函数,它们都遵循相似的模式但有不同的初始化参数。以下是对这些构造函数的详细分析:
1. 默认构造函数
rpc_client()
: socket_(ios_),
work_(std::make_shared<asio::io_context::work>(ios_)),
deadline_(ios_),
body_(INIT_BUF_SIZE) {
thd_ = std::make_shared<std::thread>([this] { ios_.run(); });
}
功能:
-
创建一个未连接到任何服务器的RPC客户端
-
初始化ASIO基础组件
初始化列表:
-
socket_(ios_)
:创建TCP socket,绑定到io_context -
work_
:创建work对象防止io_context在没有任务时退出 -
deadline_(ios_)
:初始化定时器用于超时控制 -
body_(INIT_BUF_SIZE)
:初始化接收缓冲区
构造函数体:
-
创建并启动一个线程运行io_context事件循环
2. 带语言和回调的构造函数
rpc_client(client_language_t client_language,
std::function<void(long, const std::string &)> on_result_received_callback)
: socket_(ios_),
work_(std::make_shared<asio::io_context::work>(ios_)),
deadline_(ios_),
body_(INIT_BUF_SIZE),
client_language_(client_language),
on_result_received_callback_(std::move(on_result_received_callback)) {
thd_ = std::make_shared<std::thread>([this] { ios_.run(); });
}
新增参数:
-
client_language
:指定客户端语言(CPP/JAVA) -
on_result_received_callback
:结果回调函数
特点:
-
适用于需要特殊语言处理或多语言集成的场景
-
回调函数用于异步接收结果
3. 带主机和端口的构造函数
rpc_client(const std::string &host, unsigned short port)
: rpc_client(client_language_t::CPP, nullptr, host, port) {}
特点:
-
委托构造简化代码
-
默认设置为C++客户端,无回调
-
提供最常用的连接参数形式
4. 完整参数构造函数
rpc_client(client_language_t client_language,
std::function<void(long, const std::string &)> on_result_received_callback,
std::string host, unsigned short port)
: socket_(ios_),
work_(std::make_shared<asio::io_context::work>(ios_)),
deadline_(ios_),
host_(std::move(host)),
port_(port),
body_(INIT_BUF_SIZE),
client_language_(client_language),
on_result_received_callback_(std::move(on_result_received_callback)) {
thd_ = std::make_shared<std::thread>([this] { ios_.run(); });
}
完整初始化:
-
包含所有可能的构造参数
-
使用
std::move
优化字符串参数传递 -
初始化连接目标地址(host_和port_)
总结
- 异步 I/O:使用 Asio 实现非阻塞网络通信。
- 多线程:单独线程运行
io_context::run()
,避免主线程阻塞。 - 回调机制:通过
on_result_received_callback_
处理服务端返回结果。 - 可扩展性:允许不同语言客户端接入(通过
client_language_
)。 - 资源管理:使用
shared_ptr
管理线程和work
对象,确保生命周期安全。
构造函数 | 描述 |
---|---|
默认构造函数 | 最简单初始化,适合后续手动连接 |
指定语言和回调 | 支持自定义结果处理 |
主机+端口构造函数 | 快速创建连接到某主机的客户端 |
完整构造函数 | 最常用,包含全部配置项 |