/**
 * 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;
}
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
   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;
}