15.1.3. TCP Communication with Discovery ServerΒΆ
Fast DDS Discovery Server consists on a client-server discovery mechanism, in which a server DomainParticipant operates as the central point of communication. It collects and processes the metatraffic sent by the client DomainParticipants, and then distributes the appropriate information among the rest of the clients. An extended description of the feature can be found at Discovery Server Settings.
To use TCP communication along with Discovery Server, both the server participant and the client participant need to use custom user transports. There exists several ways of configuring the server participant, being Fast DDS CLI the fastest solution:
It can be configured to work over a TCP transport layer by using the arguments -t
and -q
to set
up the IP address and the TCP port, respectively. After sourcing the environment, the following command
can be used to instantiate a server listening on localhost and port 12345 (see CLI).
fastdds discovery -i 0 -t 127.0.0.1 -q 12345
The following snippet can be used to instantiate a server on IP 192.168.10.57 listening on port 12345.
eprosima::fastdds::dds::DomainParticipantQos qos = PARTICIPANT_QOS_DEFAULT;
// Configure the current participant as SERVER
qos.wire_protocol().builtin.discovery_config.discoveryProtocol = eprosima::fastrtps::rtps::DiscoveryProtocol_t::SERVER;
// Add custom user transport with TCP port 12345
auto data_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
data_transport->add_listener_port(12345);
qos.transport().user_transports.push_back(data_transport);
// Define the listening locator to be on interface 192.168.10.57 and port 12345
constexpr uint16_t tcp_listening_port = 12345;
eprosima::fastrtps::rtps::Locator_t listening_locator;
eprosima::fastrtps::rtps::IPLocator::setIPv4(listening_locator, "192.168.10.57");
eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(listening_locator, tcp_listening_port);
eprosima::fastrtps::rtps::IPLocator::setLogicalPort(listening_locator, tcp_listening_port);
qos.wire_protocol().builtin.metatrafficUnicastLocatorList.push_back(listening_locator);
// Set the GUID prefix to identify this server
std::istringstream("44.53.00.5f.45.50.52.4f.53.49.4d.41") >> qos.wire_protocol().prefix;
The following snippet can be used to instantiate a server on IP 192.168.10.57 listening on port 12345.
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<profiles>
<transport_descriptors>
<transport_descriptor>
<transport_id>server_tcp_transport</transport_id>
<type>TCPv4</type>
<!--
Set listening port for the transport.
This port is where the clients will connect.
-->
<listening_ports>
<port>12345</port>
</listening_ports>
</transport_descriptor>
</transport_descriptors>
<participant profile_name="TCP_SERVER" is_default_profile="true">
<rtps>
<builtin>
<discovery_config>
<discoveryProtocol>SERVER</discoveryProtocol>
</discovery_config>
<metatrafficUnicastLocatorList>
<locator>
<tcpv4>
<address>192.168.10.57</address>
<port>12345</port>
<physical_port>12345</physical_port>
</tcpv4>
</locator>
</metatrafficUnicastLocatorList>
</builtin>
<prefix>44.53.00.5f.45.50.52.4f.53.49.4d.41</prefix>
<useBuiltinTransports>false</useBuiltinTransports>
<userTransports>
<transport_id>server_tcp_transport</transport_id>
</userTransports>
</rtps>
</participant>
</profiles>
</dds>
It can be configured to work over a TCP transport layer by using the argument --transport tcpv4
. The IP
address and the TCP port can be set up with arguments --listening-address
and --listening-port
,
respectively. From the DiscoveryServerExample folder, the following command can be used to instantiate a
server listening on localhost and port 12345.
./DiscoveryServerExample server --transport tcpv4 --listening-address 127.0.0.1 --listening-port 12345
The client participant can be configured by either using the ROS_DISCOVERY_SERVER
environment variable (see
ROS_DISCOVERY_SERVER) or by manually setting it.
To configure a client participant to communicate over the TCP transport layer with the
ROS_DISCOVERY_SERVER
environment variable, the prefix TCPv4 needs to be used. The following command
can be used to configure the variable to set up a client using TCP communication and connecting to a
server on localhost and port 12345.
export ROS_DISCOVERY_SERVER=TCPv4:[127.0.0.1]:12345
The following snippet can be used to instantiate a client that will try to connect to a server on IP 192.168.10.57 and port 12345, that is, the server instantiated above.
eprosima::fastdds::dds::DomainParticipantQos qos = PARTICIPANT_QOS_DEFAULT;
// Configure the current participant as SERVER
qos.wire_protocol().builtin.discovery_config.discoveryProtocol = eprosima::fastrtps::rtps::DiscoveryProtocol_t::CLIENT;
// Add custom user transport with TCP port 0 (automatic port assignation)
auto data_transport = std::make_shared<eprosima::fastdds::rtps::TCPv4TransportDescriptor>();
data_transport->add_listener_port(0);
qos.transport().user_transports.push_back(data_transport);
// Define the server locator to be on interface 192.168.10.57 and port 12345
constexpr uint16_t server_port = 12345;
eprosima::fastrtps::rtps::Locator_t server_locator;
eprosima::fastrtps::rtps::IPLocator::setIPv4(server_locator, "192.168.10.57");
eprosima::fastrtps::rtps::IPLocator::setPhysicalPort(server_locator, server_port);
eprosima::fastrtps::rtps::IPLocator::setLogicalPort(server_locator, server_port);
// Define the server attributes
eprosima::fastrtps::rtps::RemoteServerAttributes remote_server_att;
remote_server_att.metatrafficUnicastLocatorList.push_back(server_locator);
// Set the GUID prefix to identify this server
std::istringstream("44.53.00.5f.45.50.52.4f.53.49.4d.41") >> remote_server_att.guidPrefix;
// Add the server
qos.wire_protocol().builtin.discovery_config.m_DiscoveryServers.push_back(remote_server_att);
The following snippet can be used to instantiate a client that will try to connect to a server on IP 192.168.10.57 and port 12345, that is, the server instantiated above.
<?xml version="1.0" encoding="UTF-8" ?>
<dds xmlns="http://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">
<profiles>
<transport_descriptors>
<transport_descriptor>
<transport_id>client_tcp_transport</transport_id>
<type>TCPv4</type>
<!--
Set listening port for the transport to 0.
This automatically assigns a port.
-->
<listening_ports>
<port>0</port>
</listening_ports>
</transport_descriptor>
</transport_descriptors>
<participant profile_name="TCP_CLIENT" is_default_profile="true">
<rtps>
<builtin>
<discovery_config>
<discoveryProtocol>CLIENT</discoveryProtocol>
<discoveryServersList>
<RemoteServer prefix="44.53.00.5f.45.50.52.4f.53.49.4d.41">
<!--
Server locator specifying where it is listening
-->
<metatrafficUnicastLocatorList>
<locator>
<tcpv4>
<address>192.168.10.57</address>
<port>12345</port>
<physical_port>12345</physical_port>
</tcpv4>
</locator>
</metatrafficUnicastLocatorList>
</RemoteServer>
</discoveryServersList>
</discovery_config>
</builtin>
<useBuiltinTransports>false</useBuiltinTransports>
<userTransports>
<transport_id>client_tcp_transport</transport_id>
</userTransports>
</rtps>
</participant>
</profiles>
</dds>