.. include:: vars.rst .. _section-gsg_intro_discovery: Discovery ********* .. list-table:: :name: TableDiscoveryPrerequisites :widths: 20 80 :header-rows: 0 * - Prerequisites - .. only:: cpp98 or cpp11 * :ref:`section-gsg_intro_cpp11` .. only:: csharp * :ref:`section-gsg_intro_cpp11` * Repository cloned from GitHub `here `_ * - Time to complete - 30 minutes * - Concepts covered in this module - - Discovery - Domains - DomainParticipants Before we talk about discovery, we should talk about the |DP| entity that you create when you create your DDS application. If you walk through all of the code we have used so far, you will see that creating a |DP| is nearly the first step our applications take, and a |DP| is used to create all the *Publishers*, *Subscribers* (and ultimately the |DWs| and |DRs|) your application uses. When you create a |DP|, it starts the discovery process. .. only:: cpp11 .. code-block:: C++ // A DomainParticipant allows an application to begin communicating in // a DDS domain. Typically there is one DomainParticipant per application. // Uses TemperingApplication profile to set participant name. dds::domain::DomainParticipant participant( domain_id, qos_provider.participant_qos( "ChocolateFactoryLibrary::TemperingApplication")); .. admonition:: Definition :class: definition-alert Discovery is the process in which |DPs| find out about other |DPs| and exchange information about their |DWs| and |DRs|. When a |DP| learns about the |DWs| and |DRs| belonging to another |DP|, it analyzes whether they have matching *Topics*, datatypes, and compatible QoS with its own |DRs| and |DWs|. If a |DW| and |DR| are determined to be compatible, they communicate. By default, discovery starts as soon as you create a |DP| in your application. Discovery is an ongoing process—whenever |DWs| and |DRs| are created, modified, or deleted, their |DP| sends that information to the other |DPs| in the system. In addition, |DPs| maintain their liveliness in the system using periodic discovery announcements. .. figure:: static/discovery/discovery.png :scale: 40 % :alt: Simplified Discovery Diagram :name: SimplifiedDiscovery :align: center Simplified discovery diagram. All |DPs| in your system will send discovery information at startup (by default), and they will all determine whether they have |DWs| and |DRs| that match. Any time you create a new |DW| or |DR| in your application, its |DP| will announce the existence of the new |DW| or |DR| to all the |DPs| it has discovered. .. tip:: Notice that creating a |DP| means creating discovery traffic over the network. This is one reason we recommend you create as few |DPs| as possible, according to your system design. Often there is only one |DP| per application with multiple |DRs| and |DWs| underneath it, but that may depend on the number of domains you need. Domains ======= When you create a |DP|, you pass it a positive integer value that represents the DDS domain it should communicate in. A DDS domain is a logical DDS network. If you create |DPs| in different domains, they will not communicate with each other. .. tip:: Using multiple domains is not a way to secure your DDS system, but it is a way to keep DDS applications that should not communicate from interfering with each other or from using unnecessary resources storing information about |DWs| or |DRs| they will never communicate with. For information on securing a DDS system, see the :link_sec_gsg:`Security Plugins Getting Started Guide `. There are many reasons for creating multiple DDS domains. For example: - You need to run a production system and a test system on the same network, and you do not want them to communicate with each other. - You have multiple developers running tests, and you don’t want them to collide with each other - You have different subsystems in your overall system, and they don’t need to communicate with each other. - You are using Connext DDS Secure, and you want to support both a secure domain and a non-secure domain in your system. .. Sometimes, you may have an application that needs to interact in multiple DDS domains. It does that by creating a |DP| for each domain it wants to communicate in. .. figure:: static/discovery/dps_domains.png :scale: 40 % :alt: DomainParticipants in Different Domains :name: DPDiffDomains :align: center |DPs| in different domains do not send announcements to each other. Initial Peers ============= The initial peers define where a |DP| sends its first announcements. These peers are a list of addresses (in string format) that a |DP| should attempt to contact. |CONNEXT| can support transports other than UDP, so these strings use a format called a “locator” that allows you to specify which transport as well as the address. The details on how to format locator strings can be found in :link_connext_locators_um:`RTPS Locators and IP Mobility, in the RTI Connext DDS Core Libraries User's Manual <>`. Most of the time you will be specifying locators that look like normal host names and IP addresses. By default, a |DP| sends its announcements to: - A multicast IP address with a port associated with the domain the participant is communicating in. - Loopback IP address with ports associated with the domain the participant is communicating in. - A shared memory locator with an ID associated with the domain the participant is communicating in. If you need to change the initial peers your |DPs| contact, you can do that a few different ways, but the easiest way is in the XML configuration file: .. code-block:: xml IP address of machine to contact Hands-On 1: Troubleshooting Discovery ===================================== Discovery may not work for a number of reasons. The most common reasons for discovery not working (or appearing not to work) are: - A firewall is blocking some or all DDS traffic. - There is a router in your network that is not allowing multicast traffic through. - Discovery is working, but your *Topic* names are misconfigured. - Discovery is working, but your QoS profiles are misconfigured. To troubleshoot whether there is DDS communication going between applications, we will use the *rtiddsping* utility. This is a simple utility that sends ping messages over DDS from a |DW| to a |DR|, and can help determine whether an issue is with discovery or with misconfiguration. This is more interesting when run on multiple machines, but you can do this hands-on on a single machine to understand how to do this simple troubleshooting step. #. In one terminal, run *rtiddsping*: .. tabs:: .. group-tab:: Linux .. code-block:: console $ /bin/rtiddsping .. group-tab:: macOS .. code-block:: console $ /bin/rtiddsping .. group-tab:: Windows .. code-block:: doscon > \bin\rtiddsping.bat #. In a second terminal, run *rtiddsping* with the ``-subscriber`` parameter: .. tabs:: .. group-tab:: Linux .. code-block:: console $ /bin/rtiddsping -subscriber .. group-tab:: macOS .. code-block:: console $ /bin/rtiddsping -subscriber .. group-tab:: Windows .. code-block:: doscon > \bin\rtiddsping.bat -subscriber After you start both applications, you should see the following output in the *rtiddsping* publishing application: .. code-block:: text RTI Connext DDS Ping built with DDS version: 6.1.0 (Core: 1.9a.00, C: 1.9a.00, C++: 1.9a.00) Copyright 2012 Real-Time Innovations, Inc. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sending data... value: 0000000 Found 1 additional ping subscriber(s). Current subscriber tally is: 1 Sending data... value: 0000001 Sending data... value: 0000002 Sending data... value: 0000003 Sending data... value: 0000004 Sending data... value: 0000005 Sending data... value: 0000006 You should see the following output in the *rtiddsping* subscribing application: .. code-block:: text RTI Connext DDS Ping built with DDS version: 6.1.0 (Core: 1.9a.00, C: 1.9a.00, C++: 1.9a.00) Copyright 2012 Real-Time Innovations, Inc. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ rtiddsping is listening for data, press CTRL+C to stop it. Found 1 additional ping publishers(s). Current publisher tally is: 1 Found 1 additional alive ping publishers(s). Current alive publisher tally is: 1 rtiddsping, issue received: 0000001 Detected Missed Sample(s) current: 1 cumulative: 1 (50.0)% rtiddsping, issue received: 0000002 rtiddsping, issue received: 0000003 rtiddsping, issue received: 0000004 rtiddsping, issue received: 0000005 rtiddsping, issue received: 0000006 If you do not see “issue received” messages in the subscribing *rtiddsping* application, there is likely an issue with a firewall or with your network. Now, try running *rtiddsping* with the option ``-peer``. Specify the IP address of the machine where you are running the other *rtiddsping* application. This will help you determine whether there is an issue with multicast (perhaps due to a router between your machines). If communication occurs when you specify a peer, it is likely that there is no multicast available between your machines. This means that you may need to specify initial peers when running your applications. For further troubleshooting steps, see this HOWTO article on the RTI community site: `HOWTO Do Basic Debugging for System-Level DDS `__. Hands-On 2: Start Applications in Different Domains =================================================== All of the applications we have built so far can take a parameter to start in a different domain than the default. Go back to any one of the previous examples, and start one of the applications with ``-d 1``. Notice that it doesn’t communicate with applications that are not in the same domain. For example: #. Start two applications. .. only:: cpp11 In the ``6_content_filters/c++11/build`` directory, type the following, depending on your operating system: .. only:: cpp98 In the ``6_content_filters/c++98/build`` directory, type the following, depending on your operating system: .. only:: cpp98 or cpp11 .. tabs:: .. group-tab:: Linux .. code-block:: console $ ./monitoring_ctrl_application -d 1 $ ./tempering_application -d 0 .. group-tab:: macOS .. code-block:: console $ ./monitoring_ctrl_application -d 1 $ ./tempering_application -d 0 .. group-tab:: Windows .. code-block:: doscon > Debug\monitoring_ctrl_application.exe -d 1 > Debug\tempering_application.exe -d 0 (If you need, see the instructions for compiling and running the applications using CMake in :numref:`section-gsg_keys_handson1`.) .. only:: csharp In the ``6_content_filters/csharp/`` directory, type the following: .. code-block:: console $ dotnet run -p MonitoringCtrlApplication -- -domain-id 1 $ dotnet run -p TemperingApplication -- -domain-id 0 Notice that the two applications do not communicate, because they are in different domains. |br| |br| #. Open *Admin Console* and see that there are two domains in your system: domain 0 and domain 1. You can see that the ChocolateLotState and ChocolateTemperature *Topics* exist in both domains. .. figure:: static/discovery/ac_domains.png :scale: 50 % :alt: Domains in Admin Console :name: ACDomains :align: center Click on domain 0. You can see which |DWs| and |DRs| are communicating within domain 0. For example, you can see there are no |DRs| and one |DW| of the ChocolateTemperature Topic: .. figure:: static/discovery/ac_domains_entities_detail.png :scale: 50 % :alt: Entities in Domains in Admin Console :name: ACDomainsEntitiesDetail :align: center Next Steps ========== Contratulations! You have learned the basics of discovery, domains, and initial peers. You have also learned about one of the utilities that can help you troubleshoot discovery issues. For more details on discovery, see :link_connext_disc_users_man:`Discovery, in the RTI Connext DDS Core Libraries User's Manual <>`