Examples on how to use the request-reply API.
More...
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
Error handling
- Note
- To use Request-Reply you need to build and link your application with the additional
rticonnextmsgcpp
library and include ndds/ndds_requestreply_cpp.h
.
Requester Creation
Creating a Requester with optional parameters
Basic Requester example
Taking loaned samples
Taking samples by copy
Correlating requests and replies
- Requester Creation
- Example 1) Waiting for a reply to a specific request
strcpy(request1.
data().message,
"Request 1");
strcpy(request2.
data().message,
"Request 2");
if (!received) {
std::cout << "Did not receive reply for request 2" << std::endl;
return;
}
throw std::runtime_error("postcondition failed");
}
std::cout << "Received reply for request 2: "
<< reply.
data().message << std::endl;
}
if (!received) {
std::cout << "Did not receive reply for request 1" << std::endl;
return;
}
throw std::runtime_error("postcondition failed");
}
std::cout << "Received reply for request 1: "
<< reply.
data().message << std::endl;
}
- Example 2) Correlating a reply after receiving it
strcpy(request1.
data().message,
"Request 1");
strcpy(request2.
data().message,
"Request 2");
if (!received) {
std::cout << "Replies not received" << std::endl;
return;
}
it = std::find_if(replies.
begin(), replies.
end(),
if (it != replies.
end()) {
std::cout << "Received reply for request 1: "
<< it->data().message << std::endl;
}
it = std::find_if(replies.
begin(), replies.
end(),
if (it != replies.
end()) {
std::cout << "Received reply for request 2: "
<< it->data().message << std::endl;
}
- See also
- Basic Requester example
-
Basic Replier example
Basic Requester example using SampleRef
This example is similar to Basic Requester example except it uses a SampleRef instance instead of a Sample instance.
Creating a Replier
Basic Replier example
SimpleReplier example
- Implement a listener
class MySimpleReplierListener : public SimpleReplierListener<Foo, Bar>
{
public:
Bar * on_request_available(SampleRef<Foo> request)
{
if (!request.info().valid_data) {
return NULL;
}
sprintf(_reply.data().message, "Simple reply for %s",
request.data().message);
return &_reply.data();
}
void return_loan(Bar * reply)
{
}
private:
WriteSample<Bar> _reply;
};
- And create a SimpleReplier with the listener
MySimpleReplierListener * listener = new MySimpleReplierListener();
participant, "TestService", *listener);
- This next example shows how to implement a listener for a SimpleReplier using the std::string type
class MyStringSimpleReplierListener :
public SimpleReplierListener<std::string, std::string>
{
public:
std::string * on_request_available(SampleRef<const char*> request)
{
if (!request.info().valid_data) {
return NULL;
}
_reply = std::string("Simple string reply for ") + request.data();
return &_reply;
}
void return_loan(std::string * reply)
{
}
private:
std::string _reply;
};
- See also
- Basic Requester example
Error handling example
- Catching an exception from the request-reply API
try {
replier->send_reply(reply, invalid_request_id);
std::cout << "Exception while sending reply: "
<< ex.what() << std::endl;
}
try {
replier->send_reply(reply, invalid_request_id);
} catch (const std::exception& ex) {
std::cout << "Exception while sending request: "
<< ex.what() << std::endl;
}
Configuring Request-Reply QoS profiles
If you do not specify your own QoS parameters (in connext::RequesterParams and connext::ReplierParams), a connext::Requester and connext::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="file:////rti/jenkins/workspace/connextdds_htmldocs_release_connextdds_7.0.0/build/nddsgen.2.0/resource/schema/rti_dds_qos_profiles.xsd">
<qos_library name="HelloWorld_Library">
<qos_profile name="HelloWorld_Profile" base_name="BuiltinQosLib::Generic.StrictReliable" is_default_qos="true">
<datawriter_qos>
<publication_name>
<name>HelloWorldDataWriter</name>
</publication_name>
</datawriter_qos>
<datareader_qos>
<subscription_name>
<name>HelloWorldDataReader</name>
</subscription_name>
</datareader_qos>
<domain_participant_qos>
<participant_name>
<name>HelloWorldParticipant</name>
<role_name>HelloWorldParticipantRole</role_name>
</participant_name>
</domain_participant_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 connext::Requester using this profile.
- See also
- Creating a Requester with optional parameters
-
Configuring QoS Profiles with XML