/** * This function performs the publisher role in this example. * @return 0 if a sample is successfully written, 1 otherwise. */ int publisher(int argc, char *argv[]) { int result = 0; try { /** A dds::domain::DomainParticipant is created for the default domain. */ dds::domain::DomainParticipant dp(org::opensplice::domain::default_id()); /** The Durability::Transient policy is specified as a dds::topic::qos::TopicQos * so that even if the subscriber does not join until after the sample is written * then the DDS will still retain the sample for it. The Reliability::Reliable * policy is also specified to guarantee delivery. */ dds::topic::qos::TopicQos topicQos = dp.default_topic_qos() << dds::core::policy::Durability::Transient() << dds::core::policy::Reliability::Reliable(); /** A dds::topic::Topic is created for our sample type on the domain participant. */ dds::topic::Topic<HelloWorldData::Msg> topic(dp, "HelloWorldData_Msg", topicQos); /** A dds::pub::Publisher is created on the domain participant. */ std::string name = "HelloWorld example"; dds::pub::qos::PublisherQos pubQos = dp.default_publisher_qos() << dds::core::policy::Partition(name); dds::pub::Publisher pub(dp, pubQos); /** The dds::pub::qos::DataWriterQos is derived from the topic qos and the * WriterDataLifecycle::ManuallyDisposeUnregisteredInstances policy is * specified as an addition. This is so the publisher can optionally be run (and * exit) before the subscriber. It prevents the middleware default 'clean up' of * the topic instance after the writer deletion, this deletion implicitly performs * DataWriter::unregister_instance */ dds::pub::qos::DataWriterQos dwqos = topic.qos(); dwqos << dds::core::policy::WriterDataLifecycle::ManuallyDisposeUnregisteredInstances(); /** A dds::pub::DataWriter is created on the Publisher & Topic with the modififed Qos. */ dds::pub::DataWriter<HelloWorldData::Msg> dw(pub, topic, dwqos); /** A sample is created and then written. */ HelloWorldData::Msg msgInstance(1, "Hello World"); dw << msgInstance; std::cout << "=== [Publisher] written a message containing :" << std::endl; std::cout << " userID : " << msgInstance.userID() << std::endl; std::cout << " Message : \"" << msgInstance.message() << "\"" << std::endl; /* A short sleep ensures time is allowed for the sample to be written to the network. If the example is running in *Single Process Mode* exiting immediately might otherwise shutdown the domain services before this could occur */ exampleSleepMilliseconds(1000); } catch (const dds::core::Exception& e) { std::cerr << "ERROR: Exception: " << e.what() << std::endl; result = 1; } return result; }
/** * Runs the subscriber role of this example. * @return 0 if a sample was successfully read by the listener and the listener * received a notification of deadline expiration successfully, 1 otherwise. */ int subscriber(int argc, char *argv[]) { int result = 0; try { /** A domain participant, topic, and subscriber are created with matching QoS to the ::publisher */ dds::domain::DomainParticipant dp(org::opensplice::domain::default_id()); dds::topic::qos::TopicQos topicQos = dp.default_topic_qos() << dds::core::policy::Durability::Transient() << dds::core::policy::Reliability::Reliable() << dds::core::policy::Deadline(dds::core::Duration(1, 0)); dds::topic::Topic<ListenerData::Msg> topic(dp, "ListenerData_Msg", topicQos); dp.default_topic_qos(topicQos); std::string name = "Listener example"; dds::sub::qos::SubscriberQos subQos = dp.default_subscriber_qos() << dds::core::policy::Partition(name); dds::sub::Subscriber sub(dp, subQos); dds::sub::qos::DataReaderQos drqos = topic.qos(); /** An ExampleDataReaderListener and dds::core::status::StatusMask for the events * StatusMask::requested_deadline_missed() and StatusMask::data_available() are * both created and then specified when creating the dds::sub::DataReader */ ExampleDataReaderListener listener; dds::core::status::StatusMask mask; mask << dds::core::status::StatusMask::data_available() << dds::core::status::StatusMask::requested_deadline_missed(); std::cout << "=== [ListenerDataSubscriber] Set listener" << std::endl; dds::sub::DataReader<ListenerData::Msg> dr(sub, topic, drqos, &listener, mask); std::cout << "=== [ListenerDataSubscriber] Ready ..." << std::endl; /** The main thread then pauses until the listener thread has received a notification * that the deadline has expired (i.e. no more messages have been received for at least * 1 second) */ int count = 0; while(! listener.deadline_expired_ && count < 20) { exampleSleepMilliseconds(1000); count++; } result = ! (listener.deadline_expired_ && listener.data_received_); /** Remove the ExampleDataReaderListener from the DataReader */ dr.listener(0, dds::core::status::StatusMask::none()); std::cout << "=== [ListenerDataSubscriber] Closed" << std::endl; } catch (const dds::core::Exception& e) { std::cerr << "ERROR: Exception: " << e.what() << std::endl; result = 1; } return result; }
virtual void run(const dds::domain::DomainParticipant& dp, const dds::topic::Topic<T>& topic, const Params& params) { dds::pub::qos::PublisherQos pqos = dp.default_publisher_qos() << Partition("ishapes"); dds::pub::Publisher pub(dp, pqos); dds::pub::qos::DataWriterQos dwqos = pub.default_datawriter_qos() << Durability::Transient() << Reliability::Reliable(); dds::pub::DataWriter<T> dw(pub, topic, dwqos); const uint32_t period = params.period; const uint32_t samples = params.samples; uint32_t sleep_time = period * 1000; srand(clock()); const uint32_t x0 = 10; const uint32_t y0 = 10; const uint32_t r = 200; const uint32_t dx = 5; const uint32_t dy = 7; // AnyDataWriter work just fine... AnyDataWriter adw = dw; DataWriter<ShapeType> xdw = adw.get<ShapeType>(); std::cout << "Topic Name = " << xdw.topic().name() << "\tType Name = " << xdw.topic().type_name() << std::endl; // ShapeType s = {params.color, x0, y0, params.shape_size}; ShapeType s = {params.color.c_str(), x0 , y0, params.shape_size}; std::cout << ">> Writing Data..."; std::flush(std::cout); for (uint32_t i = 0; i < samples; ++i) { // Regular write dw.write(s); // Stream write dw << s; s.x = (s.x + dx) % r; s.y = (s.y + dy) % r; exampleSleepMilliseconds(sleep_time); // period is in ms } }
/** * Runs the subscriber role of this example. * @return 0 if a sample is successfully read, 1 otherwise. */ int subscriber(int argc, char *argv[]) { int result = 0; try { /** A domain participant and topic are created identically as in the ::publisher */ dds::domain::DomainParticipant dp(org::opensplice::domain::default_id()); dds::topic::qos::TopicQos topicQos = dp.default_topic_qos() << dds::core::policy::Durability::Transient() << dds::core::policy::Reliability::Reliable(); dds::topic::Topic<HelloWorldData::Msg> topic(dp, "HelloWorldData_Msg", topicQos); /** A dds::sub::Subscriber is created on the domain participant. */ std::string name = "HelloWorld example"; dds::sub::qos::SubscriberQos subQos = dp.default_subscriber_qos() << dds::core::policy::Partition(name); dds::sub::Subscriber sub(dp, subQos); /** The dds::sub::qos::DataReaderQos are derived from the topic qos */ dds::sub::qos::DataReaderQos drqos = topic.qos(); /** A dds::sub::DataReader is created on the Subscriber & Topic with the DataReaderQos. */ dds::sub::DataReader<HelloWorldData::Msg> dr(sub, topic, drqos); /** An attempt to take samples is made repeatedly until it succeeds, * or sixty seconds have elapsed. */ bool sampleReceived = false; int count = 0; do { dds::sub::LoanedSamples<HelloWorldData::Msg> samples = dr.take(); for (dds::sub::LoanedSamples<HelloWorldData::Msg>::const_iterator sample = samples.begin(); sample < samples.end(); ++sample) { if (sample->info().valid()) { std::cout << "=== [Subscriber] message received :" << std::endl; std::cout << " userID : " << sample->data().userID() << std::endl; std::cout << " Message : \"" << sample->data().message() << "\"" << std::endl; sampleReceived = true; } } exampleSleepMilliseconds(100); ++count; } while (!sampleReceived && count < 600); if (!sampleReceived) { std::cerr << "ERROR: Waited for 60 seconds but no sample received" << std::endl; result = 1; } } catch (const dds::core::Exception& e) { std::cerr << "ERROR: Exception: " << e.what() << std::endl; result = 1; } return result; }
/** * This function performs the MessageBoard role in this example. * @return 0 if successful, 1 otherwise. */ int MessageBoard(int argc, char *argv[]) { int result = 0; try { /** Initialise entities */ SubEntities e; /** Get the userID to ignore from the program parameters */ /** Parameters: MessageBoard [ignoreUserID] */ int ignoreUserID = 0; if(argc > 1) { ignoreUserID = atoi(argv[1]); } /** Create a DataState which will ensure the take onlys take alive messages */ dds::sub::status::DataState aliveDataState; aliveDataState << dds::sub::status::SampleState::any() << dds::sub::status::ViewState::any() << dds::sub::status::InstanceState::alive(); /** * Create a Query to ignore messages from the userID taken from the program * parameters */ std::stringstream queryString; queryString << "userID<>" << ignoreUserID; dds::sub::Query ignoreUserIDQuery(e.chatMessageReader, queryString.str()); std::cout << "MessageBoard has opened: send a ChatMessage with userID = -1 to close it....\n" << std::endl; bool terminated = false; while(!terminated) { /** * Take messages. Using take instead of read removes the messages from * the system, preventing resources from being saturated due to a build * up of messages */ dds::sub::LoanedSamples<Chat::ChatMessage> messages = e.chatMessageReader.select().content(ignoreUserIDQuery) .state(aliveDataState).take(); /** Output the username and content for each message */ for (dds::sub::LoanedSamples<Chat::ChatMessage>::const_iterator message = messages.begin(); message < messages.end(); ++message) { if(message->info().valid()) { /** Terminate if termination message is received */ if(message->data().userID() == TERMINATION_MESSAGE) { std::cout << "Termination message received: exiting..." << std::endl; terminated = true; } else { /** Create a Query to get the user with the userID from the message */ std::stringstream queryString; queryString << "userID=" << message->data().userID(); dds::sub::Query userIDQuery(e.nameServiceReader, queryString.str()); /** Get the user */ dds::sub::LoanedSamples<Chat::NameService> users = e.nameServiceReader.select().content(userIDQuery) .state(aliveDataState).read(); /** Output the username and content */ for (dds::sub::LoanedSamples<Chat::NameService>::const_iterator user = users.begin(); user < users.end(); ++user) { if(user->info().valid()) { std::cout << user->data().name() << ": " << message->data().content() << std::endl; } } } } } /** Sleep to avoid utilising too much CPU */ exampleSleepMilliseconds(100); } } catch (const dds::core::Exception& e) { std::cerr << "ERROR: Exception: " << e.what() << std::endl; result = 1; } return result; }