Edit Transport using Participant QoS Properties

4 posts / 0 new
Last post
Offline
Last seen: 5 years 8 months ago
Joined: 11/20/2012
Posts: 4
Edit Transport using Participant QoS Properties

Hello,

I'm trying to change the underlying transport of all of my participants from UDP to TCP v4 LAN.  I'm running on Windows using 4.5f.  I'm setting the transport programatically in the participant Qos at participant creation.

Could you please tell me what I am doing wrong below?  I dont receive any error notifications from DDS nor are any of my subscribers receiving any data from the Publishers. 

I've added system variable NDDS_DISCOVERY_PEERS with a value of tcpv4_lan://myhostname:myport

Also included the nddstransporttcp library as part of my build.

DDS_DomainParticipantQos participant_qos;

DDSDomainParticipantFactory::get_instance()->get_default_participant_qos(participant_qos);

participant_qos.transport_builtin.mask = DDS_TRANSPORTBUILTIN_MASK_NONE;

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.load_plugins", "dds.transport.TCPv4.tcp1",DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.library", "nddstransporttcp",
DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.create_function","NDDS_Transport_TCPv4_create", DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.parent.classid",
”NDDS_TRANSPORT_CLASSID_TCPV4_LAN”,
DDS_BOOLEAN_FALSE);

DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
"dds.transport.TCPv4.tcp1.server_bind_port", myport,
DDS_BOOLEAN_FALSE);

participant = DDSTheParticipantFactory->create_participant (domainId,
participant_qos, NULL, DDS_STATUS_MASK_NONE);


(All participants are created sucessfully but the data is not received by the subscribers).  Note:  the same code above is used to create the Publisher and Subscriber domain participants.   Both participants are on the same machine.

Thank you for your help.

Fernando Garcia's picture
Offline
Last seen: 2 weeks 3 days ago
Joined: 05/18/2011
Posts: 196

Hi Techgeek,

I have written a simple example application that illustrates how to use the TCP v4 LAN transport. It sets up the participant following the settings you added in your post.

Note that the Publisher and Subscriber application's participants share the same QoS settings I set in the snippet below. The only difference is that the value of dds.transport.TCPv4.tcp1.server_bind_port is different in the Publisher and Subscriber applications (i.e., 7400 in the Publisher application, and 7401 in the Subscriber application). The reason for using different ports is to be able to test the application using localhost.

    char myport[5] = "7400" // Set it to 7401 in the subscriber application
    DDSDomainParticipantFactory::get_instance()->get_default_participant_qos(participant_qos);
    
    participant_qos.transport_builtin.mask = DDS_TRANSPORTBUILTIN_MASK_NONE;
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.load_plugins", 
					     "dds.transport.TCPv4.tcp1",
					     DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.TCPv4.tcp1.library",
					     "nddstransporttcp",
					     DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property(participant_qos.property,
					     "dds.transport.TCPv4.tcp1.create_function",
					     "NDDS_Transport_TCPv4_create", 
					     DDS_BOOLEAN_FALSE);

    DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
					      "dds.transport.TCPv4.tcp1.parent.classid",
					      "NDDS_TRANSPORT_CLASSID_TCPV4_LAN",
					      DDS_BOOLEAN_FALSE);
    
    DDSPropertyQosPolicyHelper::add_property (participant_qos.property,
					      "dds.transport.TCPv4.tcp1.server_bind_port",
					      myport,
					      DDS_BOOLEAN_FALSE);

To run the example unzip tcpv4_lan_example on any directory and run rtiddsgen to generate makefiles or Visual Studio projects you will need to compile. Note that you will see some warning messages because as of the existing files will not be replaced with updated content by rtiddsgen.

rtiddsgen -example i86Linux2.6gcc4.4.3 -language C++ hello_tcp.idl
File /home/fgarcia/rti/test/tcpv4_lan_example/hello_tcp_subscriber.cxx already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
File /home/fgarcia/rti/test/tcpv4_lan_example/hello_tcp_publisher.cxx already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
File /home/fgarcia/rti/test/tcpv4_lan_example/USER_QOS_PROFILES.xml already exists and will not be replaced with updated content. If you would like to get a new file with the new content, either remove this file or supply -replace option.
Done

Then, compile your application using Visual Studio or make.

make -f makefile_hello_tcp_i86Linux2.6gcc4.4.3

Before running the application you have to configure a few things. First, you will need to add the NDDSHOME/lib/<platform_name> directory to Path, if you are using Windows; or LD_LIBRARY_PATH, if you are using Linux. The reason to add this folder to your environment, is that we configured the participant to load nddstransporttcp.dll (or libnddstransporttcp.so in Linux) without specifying its location. For instance on Linux, assuming we have already set NDDSHOME and you are using BASH:

export LD_LIBRARY_PATH=$NDDSHOME/ndds.5.0.0/lib/i86Linux2.6gcc4.4.3:LD_LIBRARY_PATH

Then, set the NDDS_DISCOVERY_PEERS on both Publisher's and Subscriber's application environment and run the applications. On the Publisher side, remember dds.transport.TCPv4.tcp1.server_bind_port is 7401 on the Subscriber's participant, you need to add that port to communicate with the Subscriber. Again, assuming you are using Linux and BASH:

export NDDS_DISCOVERY_PEERS=tcpv4_lan://localhost:7401
./objs/i86Linux2.6gcc4.4.3/hello_tcp_publisher 
=====================
Publisher Application
=====================
dds.transport.tcp.tcp1.server_bind_port = 7400
Writing hello, count 0
Writing hello, count 1
Writing hello, count 2
Writing hello, count 3
Writing hello, count 4
Writing hello, count 5

On the Subscriber's side, as dds.transport.TCPv4.tcp1.server_bind_port is 7401 on the Publisher run:

export NDDS_DISCOVERY_PEERS=tcpv4_lan://localhost:7400
./objs/i86Linux2.6gcc4.4.3/hello_tcp_subscriber
=======================
Subscriber Application
=======================
dds.transport.tcp.tcp1.server_bind_port = 7401
hello subscriber sleeping for 4 sec...
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 2
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 3
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 4
hello subscriber sleeping for 4 sec...

   name: "Fernando"
   count: 5

Your Subscriber application may miss the first few samples. Use TRANSIENT_LOCAL in the DataWriter and DataReader if you do not want to lose these samples (see this solution on the Knowledge Base).

Let me know if this solves your issue,

Best regards,
Fernando.

File Attachments: 
Offline
Last seen: 5 years 8 months ago
Joined: 11/20/2012
Posts: 4

Hi Fernando,

Thank you for the post, and for the sample code. 

With the TCP configuration on Windows, I receive the following error (consistently on the subscriber and randomly on the publisher):  NDDS_Transport_TCPv4_Plugin_verifySendResourceState_clientEA:detected send resource in an invalid state: SR=CONNECTING, CC=BOUND, DC=DISCONNECTED

What triggers this notification? 

I added on_publication_matched callback for writer discovery of the reader to complete before writer transmits any data.  The first few samples continue to be dropped as indicated in the note.  We thought that changing the underlying transport to TCP would address this.  Is there a mechanism to prevent losing the first few samples without using Durable or Reliable QoS or additional sleeps on the writer.  Usage of Durable/Reliable introduces delays that affect our high speed data transmission requirements.

Thank you again.

Gerardo Pardo's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 06/02/2010
Posts: 589

Hello,

Switching to a TCP transport will not solve the issue of missing the first samples.  TCP is realiable, yes. But UDP with RELIABILITY turned on is just as reliable.  

The issue of missing the first samples comes from the fact that the DataWriter writes them before it disovers the DataReader and unless the DURABILITY QoS is set to a kind different from the default (VOLATILE) these "previously written samples" are not sent to the "late joining" DataReader.

You can find more details along with guidance on how to configure the system to not lose the first samples in these two threads:

http://community.rti.com/content/forum-topic/subscriber-does-not-receive-first-sample

http://community.rti.com/kb/why-does-my-datareader-miss-first-few-samples

Gerardo