30.5 Setting Up PublisherListeners

Like all Entities, Publishers 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 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 Publisher, applications can be notified to handle the events of interest. For more general information on Listeners and Statuses, see 15.8 Listeners.

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

As illustrated in Figure 30.1: Publication Module , the PublisherListener interface extends the DataWriterListener interface. In other words, the PublisherListener interface contains all the functions in the DataWriterListener interface. There are no Publisher-specific statuses, and thus there are no Publisher-specific functions.

Instead, the methods of a PublisherListener will be called back for changes in the Statuses of any of the DataWriters that the Publisher has created. This is only true if the DataWriter itself does not have a DataWriterListener installed, see 31.4 Setting Up DataWriterListeners. If a DataWriterListener has been installed and has been enabled to handle a Status change for the DataWriter, then Connext will call the method of the DataWriterListener instead.

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

DDS_StatusMask mask = DDS_OFFERED_DEADLINE_MISSED_STATUS | 
                      DDS_OFFERED_INCOMPATIBLE_QOS_STATUS;
publisher = participant->create_publisher(
		DDS_PUBLISHER_QOS_DEFAULT, listener, mask);

or

DDS_StatusMask mask = DDS_OFFERED_DEADLINE_MISSED_STATUS | 
                      DDS_OFFERED_INCOMPATIBLE_QOS_STATUS;
publisher->set_listener(listener, mask); 

As previously mentioned, the callbacks in the PublisherListener act as ‘default’ callbacks for all the DataWriters contained within. When Connext wants to notify a DataWriter of a relevant Status change (for example, PUBLICATION_MATCHED), it first checks to see if the DataWriter has the corresponding DataWriterListener callback enabled (such as the on_publication_matched() operation). If so, Connext dispatches the event to the DataWriterListener callback. Otherwise, Connext dispatches the event to the corresponding PublisherListener callback.

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

  • The application installed a NULL DataWriterListener (meaning there are no callbacks for the DataWriter at all).
  • The application has disabled the callback for a DataWriterListener. This is done by turning off the associated status bit in the mask parameter passed to the set_listener() or create_datawriter() call when installing the DataWriterListener on the DataWriter. For more information on DataWriterListeners, see 31.4 Setting Up DataWriterListeners.

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

For example, Figure 30.8: Example Code to Create a Publisher with a Simple Listener shows how to create a Publisher with a Listener that simply prints the events it receives.

Figure 30.8: Example Code to Create a Publisher with a Simple Listener

class MyPublisherListener : public DDSPublisherListener {
public:
  virtual void on_offered_deadline_missed(
	DDSDataWriter* writer,
    	const DDS_OfferedDeadlineMissedStatus& status);
  virtual void on_liveliness_lost(
	DDSDataWriter* writer,
    	const DDS_LivelinessLostStatus& status);
  virtual void on_offered_incompatible_qos(
	DDSDataWriter* writer,
    	const DDS_OfferedIncompatibleQosStatus& status);
  virtual void on_publication_matched(
	DDSDataWriter* writer,
    	const DDS_PublicationMatchedStatus& status);
  virtual void on_reliable_writer_cache_changed(
	DDSDataWriter* writer,
    	const DDS_ReliableWriterCacheChangedStatus& status);
  virtual void on_reliable_reader_activity_changed (
	DDSDataWriter* writer,
	const DDS_ReliableReaderActivityChangedStatus& status);
};
void MyPublisherListener::on_offered_deadline_missed(
	DDSDataWriter* writer,
	const DDS_OfferedDeadlineMissedStatus& status)
{
    printf(“on_offered_deadline_missed\n”);
}
// ...Implement all remaining listeners in a similar manner...
DDSPublisherListener *myPubListener = new MyPublisherListener();
DDSPublisher* publisher = 
    participant->create_publisher(DDS_PUBLISHER_QOS_DEFAULT,
        myPubListener, DDS_STATUS_MASK_ALL);