|rss / atom|
Een onregelmatig verschijnende blog over willekeurige LabVIEW onderwerpen.
Network Streams 1 – Inter process communication in LabVIEWmaandag 21 oktober 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.
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.
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:
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:
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.
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:
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!