Setting Up SubscriberListeners

Like all Entities, Subscribers may optionally have Listeners. Listeners are user-defined objects that implement a DDS-defined interface (i.e. a pre-defined set of callback functions). Listeners provide the means for Connext DDS to notify applications of any changes in Statuses (events) that may be relevant to it. By writing the callback functions in the Listener and installing the Listener into the Subscriber, applications can be notified to handle the events of interest. For more general information on Listeners and Statuses, see Listeners.

Note: Some operations cannot be used within a listener callback, see Restricted Operations in Listener Callbacks.

As illustrated in Figure: Subscription Module , the SubscriberListener interface extends the DataReaderListener interface. In other words, the SubscriberListener interface contains all the functions in the DataReaderListener interface. In addition, a SubscriberListener has an additional function: on_data_on_readers(), corresponding to the Subscriber’s DATA_ON_READERS status. This is the only status that is specific to a Subscriber. This status is closely tied to the DATA_AVAILABLE status (DATA_AVAILABLE Status) of DataReaders.

The Subscriber’s DATA_ON_READERS status is set whenever the DATA_AVAILABLE status is set for any of the DataReaders created by the Subscriber. This implies that one of its DataReaders has received new DDS data samples. When the DATA_ON_READERS status is set, the SubscriberListener’s on_data_on_readers() method will be invoked.

The DATA_ON_READERS status of a Subscriber takes precedence over the DATA_AVAILABLE status of any of its DataReaders. Thus, when data arrives for a DataReader, the on_data_on_readers() operation of the SubscriberListener will be called instead of the on_data_available() operation of the DataReaderListener—assuming that the Subscriber has a Listener installed that is enabled to handle changes in the DATA_ON_READERS status. (Note however, that in the SubscriberListener’s on_data_on_readers() operation, you may choose to call notify_datareaders(), which in turn may cause the DataReaderListener’s on_data_available() operation to be called.)

All of the other methods of a SubscriberListener will be called back for changes in the Statuses of Subscriber’s DataReaders only if the DataReader is not set up to handle the statuses itself.

If you want a Subscriber to handle status events for its DataReaders, you can set up a SubscriberListener during the Subscriber’s creation or use the set_listener() method after the Subscriber is created. The last parameter is a bit-mask with which you should set which Status events that the SubscriberListener will handle. For example,

DDS_StatusMask mask = 
    DDS_REQUESTED_DEADLINE_MISSED_STATUS | 
    DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS;
subscriber = participant->create_subscriber(
    DDS_SUBSCRIBER_QOS_DEFAULT, listener, mask);

or

DDS_StatusMask mask = 
    DDS_REQUESTED_DEADLINE_MISSED_STATUS | 
    DDS_REQUESTED_INCOMPATIBLE_QOS_STATUS;
subscriber->set_listener(listener, mask); 

As previously mentioned, the callbacks in the SubscriberListener act as ‘default’ callbacks for all the DataReaders contained within. When Connext DDS wants to notify a DataReader of a relevant Status change (for example, SUBSCRIPTION_MATCHED), it first checks to see if the DataReader has the corresponding DataReaderListener callback enabled (such as the on_subscription_matched() operation). If so, Connext DDS dispatches the event to the DataReaderListener callback. Otherwise, Connext DDS dispatches the event to the corresponding SubscriberListener callback.

NOTE, the reverse is true for the DATA_ON_READERS/DATA_AVAILABLE status. When DATA_AVAILABLE changes for any DataReaders of a Subscriber, Connext DDS first checks to see if the SubscriberListener has DATA_ON_READERS enabled. If so, Connext DDS will invoke the on_data_on_readers() callback. Otherwise, Connext DDS dispatches the event to the Listener (on_data_available()) of the DataReader whose DATA_AVAILABLE status actually changed.

A particular callback in a DataReader is not enabled if either:

Similarly, the callbacks in the DomainParticipantListener act as ‘default’ callbacks for all the Subscribers that belong to it. For more information on DomainParticipantListeners, see Setting Up DomainParticipantListeners.

The Subscriber also provides an operation called notify_datareaders() that can be used to invoke the on_data_available() callbacks of DataReaders who have new DDS data samples in their receive queues. Often notify_datareaders() will be used in the on_data_on_readers() callback to pass off the real processing of data from the SubscriberListener to the individual DataReaderListeners.

Calling notify_datareaders() causes the DATA_ON_READERS status to be reset.

Figure: Simple SubscriberListener shows a SubscriberListener that simply notifies its DataReaders when new data arrives.

Figure: Simple SubscriberListener

class MySubscriberListener : public DDSSubscriberListener {
    public:
        void on_data_on_readers(DDSSubscriber *);
/* For this example we take no action other operations */
};
void MySubscriberListener::on_data_on_readers (DDSSubscriber *subscriber)
{
    // do global processing
    ...
// now dispatch data arrival event to specific DataReaders
subscriber->notify_datareaders();
}

© 2018 RTI