Blog

 rss / atom

An irregular appearing blog about random LabVIEW topics.

Network Streams 1 – Inter process communication in LabVIEW

Monday 21 October 2013

In LabVIEW there are several ways to have different LabVIEW applications (i.e. VIs not within the same application context) communicate with each other. I'm not going to name them all here, nor am I going to list what method of communication is better for this or for that. Here is a pointer to where you can find an excellent listing and explanation of Using the Right Networking Protocol.

Here I will merely say that when you're looking for a simpler alternative to TCP or queue-like behavior across the network, network streams just might be the thing for you.

Network streams is one-way, point-to-point buffered communication.

Network streams schematic

Some of the key points that speak for using Network streams are:

  • Takes care of some of the low-level TCP/IP complexity, thus easier to user
  • They are ideal for high throughput data streaming with through-puts comparable to TCP
  • Also usable for low latency command sending
  • Direct support for most LabVIEW datatypes

In this and the following posts, we'll see some of these points put to use as we dive deeper in using network-streams in your applications.

Creating a network stream

To establish a network stream you need to call the Create Network Stream Writer Endpoint on the writer (or Host) side and the Create Network Stream Reader Endpoint on the reader (or Client) side.

Create Network Stream endpoints

Depending on your LabVIEW version (Network Streams have been available since LabVIEW 2010) you might or might not have the element allocation mode input.

Now let's focus on the mandatory inputs to be able to establish a valid network stream.

Writer name / reader name (and reader url / writer url)

LabVIEW identifies stream endpoints with a URL. A full URL is as follows:

ni.dex://host_name:context_name/endpoint_name

Where ni.dex is the protocol, which is inferred by LabVIEW so you don't have to actually specify it, hostname is the DNS name or IP address of the computer on which the endpoint you refer to resides and the optional context_name identifies which application context the endpoint resides in. The context_name you will probably only use if you have multiple application instances on one system that all use network streams.

The endpoint_name is the actual name of the endpoint and can also be build up as a hierarchical path of strings using forward slashes. I strongly recommend the use of this in complex systems that use multiple network streams. For example in the case of an application where we would have several sub-systems, each containing streams named MeasDataStream and Command stream the URL's to identify endpoints could look like:

//localhost/SubSystem 1/MeasDataStream
//localhost/SubSystem 1/Commands
//localhost/SubSystem 2/MeasDataStream
//localhost/SubSystem 2/Commands

etc..

For specifying the writer name as well as the reader name inputs, it's sufficient to just specify the endpoint_name part. LabVIEW will infer localhost for the hostname. If you do specify the hostname part explicitly, note that this can only be localhost or the IP address of the machine the code is executing on. (You can only create an endpoint on the local machine.)

It's different for the reader url and writer url parameters. At least one of those must be specified in order to establish the stream. What you specify here is the URL pointing to the 'other side's' endpoint. So for hostname you would specify the IP address or DNS name of the system on which the endpoint of the other side of the stream resides and for endpoint_name you specify the exact name of that endpoint.

Example:

Let's say you need to create a network stream for writing data from one machine (with IP address 192.168.178.42) to some other machine. The following code will do just that:

Establish a Network Stream example

The code on the left will just create a writer endpoint named CmdWriter and wait until some reader connects to it. In this case it will wait indefinitely because we didn't specify a timeout. The code on the right will create the reader endpoint named CmdReader and attempt to connect to the writer endpoint on the other system. If that endpoint does not exist (yet), it will keep on trying indefinitely because here the default timeout is also -1. If both endpoints are created successfully, both create functions return and the stream is ready to be used for sending data.

Note that the endpoint that specifies the remote endpoint URL (in this case the reader) will be the system that handles the background connection handling (e.g. re-connecting in case of connection loss). If both endpoints specify the remote URL, it is undetermined which one will be in charge of connection handling. It is recommended that only one side specifies the URL for the other side.

Buffer size and Data type

In the example here I used 100 as the buffer size on both endpoints and String as the data-type. The buffer size strongly depends on your application. For high-throughput applications you should do some benchmarking to determine the optimal buffer size. For command sending, the buffer size can be quite small.

In the next post we'll dive deeper into data-types for network streams and connection management.

Keep your threads running and data flowing!
Jeffrey Habets


Comments

Leave this one empty:
Name*
Don't fill in data here:
Comment*
Don't put anythin in here:

Jeffrey Habets - Monday 26 October 2015

First off all, sorry I did not respond sooner to your message Gerrit and Cristian. Somehow the e-mail notification system for the blog got messed up and I did not get notified.

@Cristian: The context_name part is indeed only necessary if you have multiple applications on the same system using network streams. In most use-cases (two systems - each having one application - talking to each other through network streams) the context_name can be omitted though.

@Gerrit: I have a next post in the pipeline for sometime now, but the pipeline unfortunately keeps getting filled with other stuff. For now, have a look at the presentation here Network Streams (It's the top one in our downloads section). Slide 16-18 talk about connection management. What you are looking for is basically described on slide 18 I think. Internally we implemented this concept of a connection watchdog in an active object we call the SuperNS. This is bound to be released as an opensource vi-package in the near future. But if you want to have a look at it sooner, just drop me a mail and I will be happy to send it to you in its current incarnation.

Gerrit van Donk - Monday 24 August 2015

"In the next post we'll dive deeper into data-types for network streams and connection management". Would love to learn more about connection management. Now we're using network streams both for lossless data transfer and sending commands. We're (almost) always woking in the LabVIEW development environment and I'd like to have an easy way to handle accidental disconnections. After disconnection the RT target should continue running doing the stuff it was programmed for and as soon connection is up again it should resume sending data. I don't care if in the meantime some data is lost. Have you already posted some thoughts/examples on this topic?

Cristian Marinescu - Monday 14 July 2014

Returning more precise ... I used edpoint's name specifying the context, so "/ /: CONTEXT_NAME / endpoint_name" and the URL name I put "/ / machine_ip: CONTEXT_NAME / endpoint_name". In this way I was able to generate more connections in both directions between the two computers. I used the same two applications built with Application Builder Labview2013 after I set the option "allowmultipleinstances = true" in the ini file. I have only one problem: I can not make a connection with both endpoints on the same computer. I turn on the reader or the writer then if you try to start and complementary application, it generates error -314 350 (Another application is already streaming on to an endpoint in the context you specified. If you specified a connection name in the reader name writer or terminal name of the endpoint, you must specify an unused context name. If you DID not specify a context name, you must specify an unused context name by Entering an endpoint URL into the reader or writer name terminal name.). I mention that I used an unused context name to another stream. However, running the two VIs in LabVIEW development environment, the connection can be made locally.

Cristian Marinescu - Monday 14 July 2014

I tried to communicate between two computers with an endpoint on a computer and the other on the second, it worked perfectly. I tried the development version of the two VIs (reader) and (writer) and have worked on the same machine. Compiled version of the two VIs do not work on the same machine. In contrast works well on two different computers. If I try to attach a version compiled endpoint and the other endpoint in development version does not work. I tried to run the two applications in multiple instances, so as to realize the second link between the two computers, but when I try to start the second link, it can not be established. Suspect that the problem is related to context even though I used different names for pairs of endpoints. So I tried to enter the URL name context. When you enter a context name (eg "/ / localhost: mycontext/reader1" or "/ / 192.168.0.3: mycontext/writer2"), I could not perform any connection. "CONTEXT_NAME" is a name that you can choose arbitrarily? In your post, as in Labview documentation, the complete form of the URL is / / machine_name: contex_name / endpoint_name. But in an example you wrote / / localhost/Subsytem1/Command for endpoint and / / localhost/Subsystem2/Command for another endpoint of another stream. I have to replace ':' with '/'?

Jeffrey Habets - Thursday 24 October 2013

Hi Steen, Good question! As far as I know there is no server backend needed for using Network Streams (NS). The only thing NS have in common with shared variables is that they use the same thin network layer on top of TCP/IP, that is LogosXT. NS is a point-to-point connection, so there's nothing in-between. Each connection you set-up in the way described above will launch it's own background process to manage the connection. (I think this is basically functionality that is present in the LogosXT layer. Also used by SVE, but there all shared variables connecting two systems will share the same background process.) You can use NS out of the box on a standard LV Windows installation. For real-time targets you need to make sure to install the NS support on the target. Jeffrey

Steen Schmidt - Thursday 24 October 2013

Hi Jeffrey, With Network Streams, as with Shared Variables, your system needs to run a server backend that hosts the Network Streams, right? Analogous to the SVE for Shared Variables. Do you have any experience with how much/little this loads the systems that use Network Streams, and if that server has the same flaky nature as is sometimes seen with the SVE? Cheers, Steen