Case1

ROS2如下代码,经常出现客户端发送异步请求没有收到回调的情况:

std::unordered_map TaskManager::getAllNodes() {

if (!get_cur_host_nodes_status_cli_->wait_for_service(std::chrono::duration(1))) {

MOGO_WARN("cannot call service to get cur host nodes because of [/ssm/query_agent_state] is not available");

return {};

}

get_cur_host_nodes_status_cli_->prune_pending_requests(); // 加上这一行解决问题

auto request = std::make_shared();

auto response = std::make_shared();

std::vector bytes(hostname_.begin(), hostname_.end());

request->req = bytes;

bool hasCallBack = false;

using ServiceResponseFuture = mogo::Client::SharedFuture;

auto response_received_callback = [this, &hasCallBack](ServiceResponseFuture future) {

system_master::AgentInf agent_info;

auto response = future.get();

common::DeserializeProto(agent_info, response->resp);

if (response->resp.size() == 1 && response->resp[0] == '0') {

MOGO_WARN("the request host of req does not exist in the domain host maintained by ssm, the resp returned by ssm is [0]");

return;

}

if (agent_info.agent_state() == system_master::AgentState::DISCONNECT) {

MOGO_WARN("the node status of the agent may be changing and is unreliable");

return;

}

auto nodes = agent_info.node();

for (int i = 0; i < nodes.size(); i++) {

auto node = nodes.Get(i);

NodeInf node_inf;

node_inf.node_name_ = node.node_name();

node_inf.node_state_ = static_cast(node.state());

nodes_mp_[node_inf.node_name_] = node_inf;

}

hasCallBack = true;

};

auto future_result = get_cur_host_nodes_status_cli_->async_send_request(request, response_received_callback);

// mogo::spin_until_future_complete(node_handle_.get_node(), future_result) == mogo::FutureReturnCode::SUCCESS) {

// MOGO_INFO("Received response: %s", response->data.c_str());

// } else {

// MOGO_ERROR("Failed to get response within the timeout.");

// }

int count = 0;

while (!hasCallBack) {

usleep(10000);

count++;

if (!hasCallBack && count >= 100) {

MOGO_ERROR("asynchronous callback timeout, the threshold of timeout is 1s, the time slice is 10ms");

break;

}

}

return nodes_mp_;

}

        在 ROS 2 中,prune_pending_requests() 是一个用于清理挂起请求的函数。它是 rclcpp::Client 类的成员函数,用于清理尚未完成的请求,以避免请求队列中的挂起请求堆积。

        在 ROS 2 中,客户端(Client)与服务端(Server)之间进行通信时,客户端可能会向服务端发送请求并等待响应。如果客户端发送的请求在一定时间内没有得到响应,这些请求就会被视为挂起请求。这可能发生在网络延迟、服务端故障或其他原因导致请求无法完成的情况下。

   prune_pending_requests() 函数的作用是清理这些挂起请求,以确保请求队列不会无限增长。当调用这个函数时,它会检查每个挂起请求的状态,并将超时的请求从队列中移除。

以下是一个示例代码,演示了如何使用 prune_pending_requests() 函数:

#include

int main(int argc, char** argv) {

rclcpp::init(argc, argv);

auto node = std::make_shared("client_node");

// 创建客户端

auto client = node->create_client("add_two_ints");

// 发送请求(未得到响应)

auto request = std::make_shared();

request->a = 10;

request->b = 20;

auto future_result = client->async_send_request(request);

// 在发送请求后,等待一段时间

std::this_thread::sleep_for(std::chrono::seconds(5));

// 清理挂起的请求

client->prune_pending_requests();

// 检查请求是否已完成

if (future_result.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {

auto response = future_result.get();

RCLCPP_INFO(node->get_logger(), "Result: %ld", response->sum);

} else {

RCLCPP_WARN(node->get_logger(), "Request timed out.");

}

rclcpp::shutdown();

return 0;

}

        在上面的示例中,我们创建了一个客户端,向服务端发送请求,并在请求发送后等待一段时间。然后,我们调用 prune_pending_requests() 函数来清理挂起请求。最后,我们检查请求是否已完成,并根据结果进行相应的处理。

        请注意,prune_pending_requests() 函数需要运行在客户端的上下文中,因此需要在适当的地方调用该函数,例如在等待请求完成之前或之后。

        这个函数对于管理挂起请求队列很有用,可以防止队列无限增长,并确保及时处理请求超时的情况。

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: