请求-响应模式
概念理解
请求-响应(流)模式在传统请求-响应基础上增加了响应流功能:
- 服务器可以发送连续的响应流,而不是单一响应
- 任何一方可随时终止流
- 客户端销毁
pending_response对象会自动通知服务器停止发送
代码实现详解
C++客户端实现
cpp
// 1. 创建节点
#include "iceoryx2.hpp"
using namespace iox2;
auto node = NodeBuilder().create<ServiceType::Ipc>().value();
// 说明:创建IPC通信节点,实现进程间通信
// 2. 创建服务并指定数据类型
auto service = node.service_builder(ServiceName::create("autopilot").value())
.request_response<Position, State>() // 指定请求类型Position和响应类型State
.open_or_create() // 打开或创建服务
.value();
// 3. 创建客户端端口
auto client = service.client_builder().create().value();
// 说明:基于服务创建客户端,用于发送请求
// 4. 发送请求
auto request = client.loan_uninit().value(); // 申请未初始化的请求内存
auto initialized_request = request.write_payload(Position{{123.456, 789.1}}); // 初始化请求数据
auto pending_response = send(std::move(initialized_request)).value();
// 说明:移动语义转移所有权,pending_response管理响应流生命周期
// 5. 事件循环处理响应
while (node.wait(iox2::bb::Duration::from_millis(100)).has_value()) {
while (true) {
auto position = pending_response.receive().value(); // 接收响应数据
if (position.has_value()) {
show_larry_position_in_app(position.value()); // 显示当前位置
} else {
break; // 无更多数据,退出内层循环
}
// 检查连接状态
if (!pending_response.is_connected()) {
if (is_at_destination(position)) {
show_larry_arrived_popup_in_app(); // 到达目的地
} else {
show_larry_encountered_obstacle_in_app(); // 遇到障碍
}
}
}
} C++服务器实现
cpp
// 1. 服务器端初始设置(与客户端类似)
auto node = NodeBuilder().create<ServiceType::Ipc>().value();
auto service = node.service_builder(ServiceName::create("autopilot").value())
.request_response<Position, State>()
.open_or_create()
.value();
auto server = service.server_builder().create().value();
// 2. 接收请求
auto active_request = server.receive().value();
// 说明:接收客户端请求,active_request管理请求生命周期
// 3. 主处理循环
while (node.wait(iox2::bb::Duration::from_millis(100)).has_value()) {
// 检查是否有新请求
if ( !active_request.has_value() ) {
active_request = server.receive().value(); // 尝试接收新请求
if ( active_request.has_value() ) {
drive_to_position(active_request); // 开始向目标位置行驶
}
}
// 处理活动请求
if ( active_request.has_value() ) {
if ( !active_request->is_connected() ) { // 客户端断开连接
stop_driving();
active_request = iox2::bb::NULLOPT; // 清空活动请求
} else if ( arrived_at_destination() ) { // 到达目的地
active_request = iox2::bb::NULLOPT;
} else { // 正常行驶中,发送状态更新
auto response = active_request->loan_uninit().value();
auto initialized_response = response.write_payload(get_current_state());
send(std::move(initialized_response)).value();
// 说明:定期发送机器人当前状态响应
}
}
} 关键机制总结
- 双工流通信:请求后保持连接,支持持续状态更新
- 资源管理:RAII机制自动管理连接生命周期
- 非阻塞设计:轮询机制避免线程阻塞,可与其他模式结合
- 错误恢复:连接断开时双方都能检测并清理资源
相关资源
- C++最小客户端示例:展示基础请求发送
- C++最小服务器示例:展示基础请求处理
- 事件驱动通信:如何结合事件提升效率
- 黑板模式:另一种数据共享模式
这种模式特别适合需要持续状态反馈的控制场景,如机器人导航、实时监控系统等。