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
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 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
Creating a Requester
Creating a Requester with optional parameters
- Setting up a participant
- Creating a Requester with optional parameters
DomainParticipant participant =
DomainParticipantFactory.get_instance().create_participant(
0, DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
Requester<Foo, Bar> requester =
new Requester<Foo, Bar>(
new RequesterParams(
participant,
BarTypeSupport.get_instance())
.SetServiceName("TestService")
.SetQosProfile("RequestReplyExampleProfiles",
"RequesterExampleProfile"));
- See also
- Creating a Requester
Basic Requester example
- Creating a Requester
- Creating a Requester with optional parameters
- Basic Requester example
request.message = "A request";
requester.SendRequest(request);
Sample<Bar> reply = requester.CreateReplySample();
bool received = requester.ReceiveReply(reply, MAX_WAIT);
if (received)
{
if (reply.Info.valid_data)
{
Console.WriteLine("Received reply: " + reply.Data.message);
}
else
{
Console.WriteLine("Received invalid reply");
}
}
else
{
Console.WriteLine("Reply not received");
}
- Basic Requester example using the String built-in type
Requester<StringWrapper, StringWrapper> requester =
new Requester<StringWrapper, StringWrapper>(
participant, "TestServiceString",
StringTypeSupport.get_instance(),
StringTypeSupport.get_instance());
requester.SendRequest("A request");
Sample<StringWrapper> reply = requester.CreateReplySample();
bool received = requester.ReceiveReply(reply, MAX_WAIT);
if (received && reply.Info.valid_data)
{
Console.WriteLine("Received reply: " + reply.Data);
}
- Basic Requester example using DynamicData.
DynamicDataTypeSupport fooDynamicTypeSupport =
new DynamicDataTypeSupport(
Foo.get_typecode(),
new DynamicDataTypeProperty_t());
DynamicDataTypeSupport barDynamicTypeSupport =
new DynamicDataTypeSupport(
Bar.get_typecode(), new DynamicDataTypeProperty_t());
Requester<DynamicData, DynamicData> requester =
new Requester<DynamicData, DynamicData>(
participant, "TestService",
fooDynamicTypeSupport,
barDynamicTypeSupport);
DynamicData foo = (DynamicData)fooDynamicTypeSupport.create_data();
foo.set_string("message", DynamicData.MEMBER_ID_UNSPECIFIED,
"A dynamic request");
requester.SendRequest(foo);
Sample<DynamicData> reply = requester.CreateReplySample();
bool received = requester.ReceiveReply(reply, MAX_WAIT);
if (received && reply.Info.valid_data)
{
Console.WriteLine("Received reply: " +
reply.Data.get_string("message",
DynamicData.MEMBER_ID_UNSPECIFIED));
}
- See also
- Basic Replier example
Taking loaned samples
Taking samples by copy
- Get copies of the replies:
List<Sample<Bar>> replies = new List<Sample<Bar>>();
requester.TakeReplies(replies, 10);
foreach (Sample<Bar> reply in replies)
{
Console.WriteLine("Received: " + reply.Data.message);
}
IList<Sample<Bar>> newList = requester.TakeReplies(null, 10);
foreach (Sample<Bar> reply in newList)
{
Console.WriteLine("Received: " + reply.Data.message);
}
- See also
- Basic Replier example
-
Taking loaned samples
Correlating requests and replies
- Creating a Requester
- Example 1) Waiting for a reply for a specific request
WriteSample<Foo> request1 = requester.CreateRequestSample();
request1.Data.message = "Request 1";
WriteSample<Foo> request2 = requester.CreateRequestSample();
request2.Data.message = "Request 2";
requester.SendRequest(request1);
requester.SendRequest(request2);
Console.WriteLine("Waiting for reply to request2");
Sample<Bar> reply = requester.CreateReplySample();
requester.WaitForReplies(1, MAX_WAIT, request2.Identity);
requester.TakeReply(reply, request2.Identity);
Debug.Assert(
reply.RelatedIdentity.Equals(request2.Identity));
Console.WriteLine("Received reply: " + reply.Data.message);
Console.WriteLine("Waiting for reply to request1");
requester.WaitForReplies(1, MAX_WAIT, request1.Identity);
requester.TakeReply(reply, request1.Identity);
Debug.Assert(
reply.RelatedIdentity.Equals(request1.Identity));
Console.WriteLine("Received reply: " + reply.Data.message);
- Example 2) Correlate reply after receiving it
WriteSample<Foo> request1 = requester.CreateRequestSample();
request1.Data.message = "Request 1";
WriteSample<Foo> request2 = requester.CreateRequestSample();
request2.Data.message = "Request 2";
requester.SendRequest(request1);
requester.SendRequest(request2);
bool received = requester.WaitForReplies(2, MAX_WAIT);
if (!received)
{
Console.WriteLine("Replies not received");
return;
}
using (LoanedSamples<Bar> replies = requester.TakeReplies())
{
foreach (Sample<Bar> reply in replies)
{
if (reply.RelatedIdentity.Equals(request1.Identity))
{
Console.WriteLine(
"Received reply for request 1: " + reply.Data.message);
}
else if (reply.RelatedIdentity.Equals(request2.Identity))
{
Console.WriteLine(
"Received reply for request 2: " + reply.Data.message);
}
else
{
Console.WriteLine("Received unexpected reply");
}
}
}
- See also
- Basic Requester example
-
Basic Replier example
Creating a Replier
- Setting up a participant
- Creating a Replier
DomainParticipant participant =
DomainParticipantFactory.get_instance().create_participant(
domain_id, DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT,
Replier<Foo, Bar> replier = new Replier<Foo, Bar>(
participant, "TestService",
BarTypeSupport.get_instance());
- Finalizing a Replier
Basic Replier example
- Creating a Replier
- Basic Replier example
Sample<Foo> request = replier.CreateRequestSample();
bool received = replier.ReceiveRequest(request, MAX_WAIT);
if (!received)
{
Console.WriteLine("Request not received");
return false;
}
if (request.Info.valid_data)
{
Bar reply = new Bar();
reply.message = "Reply for " + request.Data.message;
replier.SendReply(reply, request.Identity);
}
- See also
- Basic Requester example
SimpleReplier example
- Implement a listener
class MySimpleReplierListener : SimpleReplierListener<Foo, Bar>
{
private Bar reply = new Bar();
public Bar OnRequestAvailable(Sample<Foo> request)
{
if (request.Info.valid_data)
{
reply.message = "Simple reply for " + request.Data.message;
return reply;
}
else
{
return null;
}
}
public void ReturnLoan(Bar reply)
{
}
}
- And create a SimpleReplier with the listener:
SimpleReplier<Foo, Bar> replier =
new SimpleReplier<Foo, Bar>(
participant, "TestService",
new MySimpleReplierListener(),
BarTypeSupport.get_instance());
- See also
- Basic Requester example
Error handling example
- Catching an exception from the request-reply API
NDDS.LogVerbosity.NDDS_CONFIG_LOG_VERBOSITY_WARNING);
WriteSample<Bar> reply = replier.CreateReplySample();
SampleIdentity_t invalidRequestId = new SampleIdentity_t();
try
{
replier.SendReply(reply, invalidRequestId);
}
catch (Retcode_BadParameter ex)
{
Console.WriteLine("Exception while sending reply: " + ex);
}
Configuring Request-Reply QoS profiles
If you do not specify your own quality of service parameters (in RTI::Connext::RequestReply::RequesterParams and RTI::Connext::RequestReply::ReplierParams<TReq,TRep>), a RTI::Connext::RequestReply::Requester<TReq,TRep> and RTI::Connext::RequestReply::Replier<TReq,TRep> 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"
version="5.3.0">
<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::Connext::RequestReply::Requester<TReq,TRep> using this profile.
- See also
- Creating a Requester with optional parameters
-
Configuring QoS Profiles with XML