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
rticonnextmsgc
library.
The examples in this section require the following header files:
#include "connext_c/connext_c_requester.h"
#include "connext_c/connext_c_replier.h"
#include "connext_c/connext_c_simple_replier.h"
Creating a Requester
- Setting up a participant
- Instantiate the declaration of a FooBarRequester, a requester that sends requests of type Foo and receives replies of type Bar (for example, in FooBarRequester.h)
#define RTI_CONNEXT_REQUESTER_DECL(TReq, TRep, TRequester)
Instantiates the declaration of a typed requester and its operations.
Definition: requester.ifc:321
Allows sending requests and receiving replies.
Definition: requester.ifc:173
A representative user-defined data type.
Definition: data.ifc:112
- Instantiate the implementation of a FooBarRequester (for example, in FooBarRequester.c)
#define TReq Foo
#define TRep Bar
#define TRequester FooBarRequester
#include "connext_c/generic/connext_c_requestreply_TReqTRepRequester.gen"
- Create a Requester
if (participant == NULL) {
printf("Error creating participant\n");
}
if (requester == NULL) {
printf("Error creating requester\n");
}
const struct DDS_DomainParticipantQos DDS_PARTICIPANT_QOS_DEFAULT
Special value for creating a DomainParticipant with default QoS.
DDS_DomainParticipant * DDS_DomainParticipantFactory_create_participant(DDS_DomainParticipantFactory *self, DDS_DomainId_t domainId, const struct DDS_DomainParticipantQos *qos, const struct DDS_DomainParticipantListener *listener, DDS_StatusMask mask)
Creates a new DDS_DomainParticipant object.
DDS_DomainParticipantFactory * DDS_DomainParticipantFactory_get_instance(void)
Gets the singleton instance of this class.
struct DDS_DomainParticipantImpl DDS_DomainParticipant
<<interface>> Container for all DDS_DomainEntity objects.
Definition: infrastructure.ifc:9781
#define DDS_STATUS_MASK_NONE
No bits are set.
Definition: infrastructure.ifc:1425
FooBarRequester * FooBarRequester_create(DDS_DomainParticipant *participant, const char *service_name)
Creates a Requester with the minimum set of parameters.
Creating a Requester with optional parameters
- Setting up a participant
- Creating a Requester with optional parameters
printf("Error creating participant\n");
}
if (requester == NULL) {
printf("Error creating requester\n");
}
#define RTI_Connext_RequesterParams_INITIALIZER
Initializes a RTI_Connext_RequesterParams instance.
Definition: requester.ifc:124
FooBarRequester * FooBarRequester_create_w_params(const RTI_Connext_RequesterParams *params)
Creates a Requester with parameters.
Contains the parameters for creating a FooBarRequester.
Definition: requester.ifc:64
char * qos_profile_name
Sets a QoS profile for the entities in this requester.
Definition: requester.ifc:94
char * service_name
The service name that Repliers and Requester use to match and communicate.
Definition: requester.ifc:74
DDS_DomainParticipant * participant
The participant this requester uses to join a DDS domain.
Definition: requester.ifc:69
char * qos_library_name
Sets the library that contains the RTI_Connext_RequesterParams::qos_profile_name.
Definition: requester.ifc:89
- See also
- Creating a Requester
-
Configuring Request-Reply QoS profiles
Requester example
- Creating a Requester
- Creating a Requester with optional parameters
Requester example
Bar * reply;
strcpy(request->message, "A Request");
reply = BarTypeSupport_create_data();
printf("Received reply: %s\n", reply->message);
} else {
printf("Received invalid reply\n");
}
printf("Reply not received\n");
} else {
printf("Error receiving reply\n");
}
BarTypeSupport_delete_data(reply);
DDS_ReturnCode_t
Type for return codes.
Definition: infrastructure.ifc:1351
@ DDS_RETCODE_OK
Successful return.
Definition: infrastructure.ifc:1354
@ DDS_RETCODE_TIMEOUT
The operation timed out.
Definition: infrastructure.ifc:1394
@ DDS_RETCODE_NO_DATA
Indicates a transient situation where the operation did not return any data but there is no inherent ...
Definition: infrastructure.ifc:1398
Foo * FooTypeSupport_create_data(void)
<<extension>> Create a data type and initialize it.
DDS_ReturnCode_t FooTypeSupport_delete_data(Foo *a_data)
<<extension>> Destroy a user data type instance.
DDS_ReturnCode_t FooBarRequester_receive_reply(FooBarRequester *self, Bar *reply, struct DDS_SampleInfo *sample_info, const struct DDS_Duration_t *max_wait)
Waits for a reply and copies its contents into a Sample.
DDS_ReturnCode_t FooBarRequester_send_request(FooBarRequester *self, const Foo *request)
Sends a request.
Information that accompanies each sample that is read or taken.
Definition: subscription.ifc:1173
DDS_Boolean valid_data
Indicates whether the DataSample contains data or else it is only used to communicate a change in the...
Definition: subscription.ifc:1221
- See also
- Replier example
-
SimpleReplier example
Taking loaned samples
- Creating a Requester
- Get iterator to loaned replies (no copies)
int i;
printf("No replies are available\n");
return;
printf("Error getting replies\n");
return;
}
for (i = 0; i < BarSeq_get_length(&replies); i++) {
Bar * reply = BarSeq_get_reference(&replies, i);
struct DDS_SampleInfo * info = DDS_SampleInfoSeq_get_reference(&infos, i);
printf("Received reply: %s\n", reply->message);
}
}
const DDS_Long DDS_LENGTH_UNLIMITED
A special value indicating an unlimited quantity.
#define DDS_SEQUENCE_INITIALIZER
An initializer for new sequence instances.
Definition: sequence.ifc:566
DDS_ReturnCode_t FooBarRequester_take_replies(FooBarRequester *self, struct BarSeq *reply_seq, struct DDS_SampleInfoSeq *sample_info_seq, DDS_Long max_count)
Provides a loaned sequence to access the existing replies.
DDS_ReturnCode_t FooBarRequester_return_loan(FooBarRequester *self, struct BarSeq *received_data, struct DDS_SampleInfoSeq *info_seq)
Returns samples previously received from the middleware.
Declares IDL sequence < DDS_SampleInfo > .
Definition: subscription.ifc:1348
- See also
- Requester example
-
Replier example
Correlating requests and replies
- Creating a Requester
- Example 1) Waiting for a reply for a specific request
Bar * reply;
strcpy(request->message, "Request 1");
strcpy(request->message, "Request 2");
printf("Did not receive reply for request 2\n");
return;
}
reply = BarTypeSupport_create_data();
requester, reply, &reply_info, &request_info2.
identity);
printf("postcondition failed\n");
}
if (reply_info.valid_data) {
printf("Received reply for request 2: %s\n", reply->message);
}
printf("Did not receive reply for request 1\n");
return;
}
requester, reply, &reply_info, &request_info1.
identity);
printf("postcondition failed\n");
}
if (reply_info.valid_data) {
printf("Received reply for request 1: %s\n", reply->message);
}
BarTypeSupport_delete_data(reply);
void DDS_SampleInfo_get_related_sample_identity(const struct DDS_SampleInfo *self, struct DDS_SampleIdentity_t *related_identity)
<<extension>> Retrieves the identity of a sample related to this one
const struct DDS_WriteParams_t DDS_WRITEPARAMS_DEFAULT
Initializer for DDS_WriteParams_t.
DDS_Boolean DDS_SampleIdentity_equals(const struct DDS_SampleIdentity_t *self, const struct DDS_SampleIdentity_t *other)
Compares this sample identity with another sample identity for equality.
DDS_ReturnCode_t FooBarRequester_take_reply_for_related_request(FooBarRequester *self, Bar *reply, struct DDS_SampleInfo *sample_info, const struct DDS_SampleIdentity_t *related_request_id)
Copies the contents of a reply for a specific request.
DDS_ReturnCode_t RTI_Connext_Requester_wait_for_replies_for_related_request(RTI_Connext_Requester *self, DDS_Long min_count, const struct DDS_Duration_t *max_wait, const struct DDS_SampleIdentity_t *related_request_id)
Waits for replies to a specific request.
DDS_ReturnCode_t FooBarRequester_send_request_w_params(FooBarRequester *self, const Foo *request, struct DDS_WriteParams_t *request_info)
Sends a request and gets back information about it that allows correlation with future replies.
Type definition for a Sample Identity.
Definition: infrastructure.ifc:9404
<<extension>> Input parameters for writing with FooDataWriter_write_w_params, FooDataWriter_dispose_w...
Definition: infrastructure.ifc:9664
struct DDS_SampleIdentity_t identity
Identity of the sample.
Definition: infrastructure.ifc:9670
The type-independent version of a Requester.
Definition: requester.ifc:53
- Example 2) Correlate reply after receiving it
int i;
strcpy(request->message, "Request 1");
strcpy(request->message, "Request 2");
printf("Replies not received\n");
return;
}
for (i = 0; i < BarSeq_get_length(&replies); i++) {
Bar * reply = BarSeq_get_reference(&replies, i);
struct DDS_SampleInfo * info = DDS_SampleInfoSeq_get_reference(&infos, i);
printf("Received reply for request 1: %s\n", reply->message);
printf("Received reply for request 2: %s\n", reply->message);
} else {
printf("Received unexpected reply\n");
}
}
DDS_ReturnCode_t RTI_Connext_Requester_wait_for_replies(RTI_Connext_Requester *self, DDS_Long min_count, const struct DDS_Duration_t *max_wait)
Waits for replies to any request.
- See also
- Requester example
-
Replier example
Creating a Replier
- Setting up a participant
- Instantiate the declaration of a FooBarReplier, a replier that receives requests of type Foo and sends replies of type Bar (for example, in FooBarReplier.h)
#define RTI_CONNEXT_REPLIER_DECL(TReq, TRep, TReplier)
Instantiates the declaration of a typed replier and its operations.
Definition: replier.ifc:357
Allows receiving requests and sending replies.
Definition: replier.ifc:244
- Instantiate the implementation of a FooBarReplier (for example, in FooBarReplier.c)
#define TReq Foo
#define TRep Bar
#define TReplier FooBarReplier
#include "connext_c/generic/connext_c_requestreply_TReqTRepReplier.gen"
- Create a Replier
if (participant == NULL) {
printf("Error creating participant\n");
}
if (replier == NULL) {
printf("Error creating replier\n");
}
FooBarReplier * FooBarReplier_create(DDS_DomainParticipant *participant, char *service_name)
Creates a Replier with the minimum set of parameters.
Replier example
- Creating a Replier
- Replier example
Bar * reply;
replier, request, &request_info, &MAX_WAIT);
printf("Request not received\n");
return 0;
}
if (request_info.valid_data) {
reply = BarTypeSupport_create_data();
sprintf(reply->message, "Reply for %s", request->message);
BarTypeSupport_delete_data(reply);
}
void DDS_SampleInfo_get_sample_identity(const struct DDS_SampleInfo *self, struct DDS_SampleIdentity_t *identity)
<<extension>> Retrieves the identity of the sample
DDS_ReturnCode_t FooBarReplier_send_reply(FooBarReplier *self, Bar *reply, const struct DDS_SampleIdentity_t *related_request_id)
Sends a reply for a previous request.
DDS_ReturnCode_t FooBarReplier_receive_request(FooBarReplier *self, Foo *request, struct DDS_SampleInfo *sample_info, const struct DDS_Duration_t *max_wait)
Waits for a request and copies its contents into a Sample.
- See also
- Requester example
SimpleReplier example
- Instantiate the declaration of a FooBarSimpleReplier, a replier that receives requests of type Foo and sends replies of type Bar (for example, in FooBarSimpleReplier.h)
#define RTI_CONNEXT_SIMPLEREPLIER_DECL(TReq, TRep, TSimpleReplier)
Instantiates the declaration of a typed SimpleReplier and its operations.
Definition: simple_replier.ifc:192
A callback-based replier.
Definition: simple_replier.ifc:143
- Instantiate the implementation of a FooBarSimpleReplier (for example, in FooBarSimpleReplier.c)
#define TReq Foo
#define TRep Bar
#define TSimpleReplier FooBarSimpleReplier
#include "connext_c/generic/connext_c_requestreply_TReqTRepSimpleReplier.gen"
- A FooBarSimpleReplier wraps a FooBarReplier, which has to be defined as well. If you haven't already, instantiate the declaration and definition of FooBarReplier as described in Creating a Replier (you can do this in the same .h and .c files you just used for FooBarSimpleReplier).
- Implement a listener
void * MySimpleReplierListener_on_request_available(
{
Bar * reply;
Foo * request = (
Foo *) request_untyped;
return NULL;
}
reply = BarTypeSupport_create_data();
sprintf(reply->message, "Simple reply for %s", request->message);
return (void *) reply;
}
void MySimpleReplierListener_on_return_loan(
void * reply)
{
BarTypeSupport_delete_data(reply);
}
The listener called by a SimpleReplier.
Definition: replier.ifc:103
- And create a SimpleReplier with the listener:
listener.
return_loan = MySimpleReplierListener_on_return_loan;
RTI_Connext_SimpleReplierListener_OnReturnLoanCallback return_loan
Returns a previously generated reply to the user.
Definition: replier.ifc:113
FooBarSimpleReplier * FooBarSimpleReplier_create(DDS_DomainParticipant *participant, char *service_name, RTI_Connext_SimpleReplierListener *listener)
Creates a new SimpleReplier.
RTI_Connext_SimpleReplierListener_OnRequestAvailableCallback on_request_available
User callback that receives a request and provides a reply.
Definition: replier.ifc:108
- See also
- Requester example
Configuring Request-Reply QoS profiles
If you do not specify your own quality of service parameters (in RTI_Connext_RequesterParams and RTI_Connext_ReplierParams), a FooBarRequester and FooBarReplier 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 FooBarRequester using this profile.
- See also
- Creating a Requester with optional parameters
-
Configuring QoS Profiles with XML