Examples on how to use the request-reply API .
Examples on how to use the request-reply API .
Request-Reply code examples.
Request-Reply Examples
Requesters and Repliers provide a way to use the Request-Reply communication pattern on top of the DDS entities. An application uses a Requester to send requests to a Replier; another application using a Replier receives a request and can send one or more replies for that request. The Requester that sent the request (and only that one) will receive the reply (or replies).
DDS Types
RTI Connext uses DDS data types for sending and receiving requests and replies. Valid types are those generated by the rtiddsgen code generator, the DDS built-in types, and DynamicData
. Refer to the Core Libraries User's Manual and the following links for more information:
Set up
Requester: sending requests and receiving replies
Replier: receiving requests and sending replies
- Note
- To use Request-Reply you need to build and link your application with the additional
rticonnextmsgcpp2
library.
Requester Creation
- Setting up a DomainParticipant
- Creating a Requester
using namespace rti::request;
Requester<Foo, Bar> requester(participant, "TestService");
<<reference-type>> Container for all dds::core::Entity objects.
Definition: TDomainParticipant.hpp:63
int32_t domain_id() const
<<extension>> Get the domain ID associated with the discovered dds::domain::DomainParticipant.
Definition: BuiltinTopicImpl.hpp:245
Creating a Requester with optional parameters
- Setting up a DomainParticipant
- Creating a Requester with additional parameters
using namespace rti::request;
RequesterParams requester_params(participant);
requester_params.service_name("TestService");
requester_params.datareader_qos(
qos_provider.
datareader_qos(
"RequestReplyExampleProfiles::RequesterExampleProfile"));
requester_params.datawriter_qos(
qos_provider.
datawriter_qos(
"RequestReplyExampleProfiles::RequesterExampleProfile"));
Requester<Foo, Bar> requester(requester_params);
<<reference-type>> The QosProvider class provides a way for a user to control and access the XML QoS ...
Definition: TQosProvider.hpp:162
const dds::pub::qos::DataWriterQos datawriter_qos()
Get the dds::pub::qos::DataWriterQos from the default profile.
Definition: TQosProvider.hpp:373
static QosProvider Default()
Get the default QosProvider.
Definition: TQosProvider.hpp:409
const dds::sub::qos::DataReaderQos datareader_qos()
Get the dds::sub::qos::DataReaderQos in the default profile.
Definition: TQosProvider.hpp:313
- See also
- Requester Creation
-
Configuring Request-Reply QoS profiles
Basic Requester example
- Requester Creation
- Creating a Requester with optional parameters
Basic Requester example
using namespace rti::request;
Foo request(
"A Request");
requester.send_request(request);
auto replies = requester.receive_replies(MAX_WAIT);
if (replies.length() == 0) {
std::cout << "Reply not received\n";
}
for (const auto& reply : replies) {
if (reply.info().valid()) {
std::cout << "Received reply: " << reply.data() << std::endl;
} else {
std::cout << "Received invalid reply\n";
}
}
An example topic-type.
Definition: types.dxx:34
- See also
- Basic Replier example
-
SimpleReplier example
Correlating requests and replies
- Requester Creation
- Example 1) Waiting for a reply to a specific request
using namespace rti::request;
Foo request1(
"Request 1"), request2(
"Request 2");
bool received = requester.wait_for_replies(1, MAX_WAIT, request_id2);
if (!received) {
std::cout << "Did not receive reply for request 2" << std::endl;
return;
}
throw std::runtime_error("did not receive any replies");
}
!= request_id2) {
throw std::runtime_error("postcondition failed");
}
if (replies[0].info().valid()) {
std::cout << "Received reply for request 2: "
<< replies[0].data() << std::endl;
}
received = requester.wait_for_replies(1, MAX_WAIT, request_id1);
if (!received) {
std::cout << "Did not receive reply for request 1" << std::endl;
return;
}
replies = requester.take_replies(request_id1);
throw std::runtime_error("did not receive any replies");
}
!= request_id1) {
throw std::runtime_error("postcondition failed");
}
if (replies[0].info().valid()) {
std::cout << "Received reply for request 1: "
<< replies[0].data() << std::endl;
}
<<move-only-type>> Provides temporary access to a collection of samples (data and info) from a DataRe...
Definition: LoanedSamplesImpl.hpp:77
unsigned int length() const
Gets the number of samples in this collection.
Definition: LoanedSamplesImpl.hpp:181
rti::core::SampleIdentity related_original_publication_virtual_sample_identity() const
<<extension>> Retrieves the information provided by related_original_publication_virtual_guid() and r...
Definition: SampleInfoImpl.hpp:304
<<extension>> <<value-type>> A SampleIdentity defines a pair (Virtual Writer Guid,...
Definition: SampleIdentity.hpp:70
- Example 2) Correlating a reply after receiving it
using namespace rti::request;
Foo request1(
"Request 1"), request2(
"Request 2");
bool received = requester.wait_for_replies(2, MAX_WAIT);
if (!received) {
std::cout << "Replies not received" << std::endl;
return;
}
auto replies = requester.take_replies();
auto it = std::find_if(
IsReplyRelatedPredicate<Bar>(request_id1));
if (it != replies.
end()) {
std::cout << "Received reply for request 1: "
<< it->data() << std::endl;
}
it = std::find_if(
IsReplyRelatedPredicate<Bar>(request_id2));
if (it != replies.
end()) {
std::cout << "Received reply for request 2: "
<< it->data() << std::endl;
}
iterator begin()
Gets an iterator to the first sample.
Definition: LoanedSamplesImpl.hpp:232
iterator end()
Gets an iterator to one past the last sample.
Definition: LoanedSamplesImpl.hpp:240
- See also
- Basic Requester example
-
Basic Replier example
Creating a Replier
Basic Replier example
- Creating a Replier
- Basic Replier example
using namespace rti::request;
for (const auto& request : requests) {
if (!request.info().valid()) {
continue;
}
Bar reply("Reply for " + request.data().message());
replier.send_reply(reply, request.info());
}
- See also
- Basic Requester example
SimpleReplier example
using namespace rti::request;
SimpleReplier<Foo, Bar> replier(
participant,
"TestService",
{
return Bar(
std::string(
"Simple reply for ") + request.message());
}
);
basic_string< char, rti::core::memory::OsapiAllocator< char > > string
A string convertible to std::string and with similar functionality.
Definition: String.hpp:266
- See also
- Basic Requester example
Configuring Request-Reply QoS profiles
If you do not specify your own QoS parameters (in RequesterParams and ReplierParams), a rti::request::Requester and rti::request::Replier are created using a default configuration. That configuration is equivalent to the one in the following QoS profile called "default":
<?xml version="1.0"?>
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../resource/schema/rti_dds_qos_profiles.xsd">
<qos_library name="RequestReplyExampleProfiles">
<qos_profile name="default">
<datawriter_qos>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time>
<sec>10</sec>
<nanosec>0</nanosec>
</max_blocking_time>
</reliability>
<history>
<kind>KEEP_ALL_HISTORY_QOS</kind>
</history>
<protocol>
<rtps_reliable_writer>
<max_heartbeat_retries>
LENGTH_UNLIMITED
</max_heartbeat_retries>
<heartbeats_per_max_samples>
2
</heartbeats_per_max_samples>
<heartbeat_period>
<sec>0</sec>
<nanosec>100000000</nanosec>
</heartbeat_period>
<fast_heartbeat_period>
<sec>0</sec>
<nanosec>10000000</nanosec>
</fast_heartbeat_period>
<late_joiner_heartbeat_period>
<sec>0</sec>
<nanosec>10000000</nanosec>
</late_joiner_heartbeat_period>
<max_nack_response_delay>
<sec>0</sec>
<nanosec>0</nanosec>
</max_nack_response_delay>
<min_nack_response_delay>
<sec>0</sec>
<nanosec>0</nanosec>
</min_nack_response_delay>
<max_send_window_size>32</max_send_window_size>
<min_send_window_size>32</min_send_window_size>
</rtps_reliable_writer>
</protocol>
<writer_resource_limits>
<max_remote_reader_filters>
LENGTH_UNLIMITED
</max_remote_reader_filters>
</writer_resource_limits>
</datawriter_qos>
<datareader_qos>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
<max_blocking_time>
<sec>10</sec>
<nanosec>0</nanosec>
</max_blocking_time>
</reliability>
<history>
<kind>KEEP_ALL_HISTORY_QOS</kind>
</history>
<protocol>
<rtps_reliable_reader>
<max_heartbeat_response_delay>
<sec>0</sec>
<nanosec>0</nanosec>
</max_heartbeat_response_delay>
<min_heartbeat_response_delay>
<sec>0</sec>
<nanosec>0</nanosec>
</min_heartbeat_response_delay>
</rtps_reliable_reader>
</protocol>
</datareader_qos>
</qos_profile>
<qos_profile name="RequesterExampleProfile"
base_name="default">
<datawriter_qos>
<durability>
<kind>TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>
</datawriter_qos>
<datareader_qos>
<durability>
<kind>VOLATILE_DURABILITY_QOS</kind>
</durability>
</datareader_qos>
</qos_profile>
<qos_profile name="ReplierExampleProfile"
base_name="default">
<datawriter_qos>
<durability>
<kind>VOLATILE_DURABILITY_QOS</kind>
</durability>
</datawriter_qos>
<datareader_qos>
<durability>
<kind>TRANSIENT_LOCAL_DURABILITY_QOS</kind>
</durability>
</datareader_qos>
</qos_profile>
</qos_library>
</dds>
You can use the profile called "RequesterExampleProfile", which modifies some parameters from the default. The example Creating a Requester with optional parameters shows how to create a rti::request::Requester using this profile.
- See also
- Creating a Requester with optional parameters
-
Configuring QoS Profiles with XML