eclipselistenerdata-distribution-service

How to create listener for publisher in CycloneDDS?


I am trying to use listeners for publishers in cyclonedds. but CycloneDDS does not have any examples on it. can someone explain how to use them in the code?

From the above link, the publisher sending data part

For this example, we'd like to have a subscriber to actually read our message. This is not always necessary. Also, the way it is done here is just to illustrate the easiest way to do so. It isn't really recommended to do a wait in a polling loop, however.

Please take a look at Listeners and WaitSets for a much better solutions, albeit somewhat more elaborate ones.

    std::cout << "=== [Publisher] Waiting for subscriber." << std::endl;
    while (writer.publication_matched_status().current_count() == 0) { // how to use a listener here? 
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

    HelloWorldData::Msg msg(1, "Hello World");
    writer.write(msg);

Wait for the subscriber to have stopped to be sure it received the, message not normally necessary and not recommended to do this in a polling loop.

    std::cout << "=== [Publisher] Waiting for sample to be accepted." << std::endl;
    while (writer.publication_matched_status().current_count() > 0) {// how to use a listener here? 
        std::this_thread::sleep_for(std::chrono::milliseconds(50));
    }

Solution

  • Listeners are installed by:

    dds_listener_t *l = dds_create_listener (...);
    dds_lset_...
    dds_set_listener (entity, l);
    

    where the "dds_lset_..." stands for setting the listener callbacks you want to install, e.g., "dds_lset_publication_matched". What it doesn't do is help you with waiting until the event happens, you'll simply get a callback. You can of course wait for a trigger on a condition variable (or the writing of a byte into a pipe or ...) and use the callback to generate that trigger.

    Using a waitset you can use the DDS API to wait for the event. For example, you could replace the polling loop in the publisher with:

    dds_entity_t ws = dds_create_waitset (participant);
    // The third argument of attach() is how the entity is
    // identified in the output from wait().  Here, we know
    // so any value will do.
    dds_waitset_attach (ws, writer, 0);
    // Wait() only returns once something triggered, and
    // here there is only a single entity attached to it,
    // with the status mask set to the only event we want
    // to wait for, so an infinite timeout and ignoring
    // the return value or list of triggered suffices for
    // the example.
    (void) dds_waitset_wait (ws, NULL, 0, DDS_INFINITY);
    

    If I were to do this "for real" I would add error checking and inspect the result of the wait call. It is only in very limited cases, like this example, that you can get away with not checking anything.