NI-Publish Subscribe Protocol (NI-PSP): NI-PSP is National Instruments’ proprietary publish-subscribe protocol (PSP). NI-PSP is composed of a server called the Shared Variable Engine that hosts values, timestamps, and other Shared Variable information. NI-PSP is designed for the use case where many accessors must access or update a latest data value. It is not designed for high data throughput or low-latency. NI-PSP is supported by a number of host servers, including Windows and LabVIEW Real-Time.
Shared Variable Engine (SVE): The SVE is a software framework that enables a networked-published Shared Variable to send values over a network. On Windows, the SVE is a Windows service (tagsrv.exe) that launches at system startup. On a real-time (RT) target, the Shared Variable Engine is an installable component that loads when the RT target boots.
Process (lvlib): A process is a LabVIEW project library that has been deployed to a Shared Variable Engine. All Shared Variables must exist within a project library; therefore, all deployed Shared Variables exist within an online process.
Network-Published Shared Variable with Buffering Enabled: Shared Variables are the objects within the Shared Variable Engine that are composed of a name (URL), data type, value, and other properties. In this document, all instances of the term “Shared Variable” refer to network-published Shared Variables with buffering enabled unless otherwise specified.
Accessor: The readers and writers of Shared Variables, which can be located in VIs, the Distributed System Manager, or elsewhere. Refer to the LabVIEW APIs for Accessing Shared Variables section of this paper for a list of accessors, such as the Static Shared Variable Node and the Programmatic Shared Variable API. A single Shared Variable can be accessed by several computers and RT targets simultaneously. Shared Variable accessors exist outside of the Shared Variable Engine and they make requests to change the value or properties of a Shared Variable or receive published changes from a Shared Variable Engine.
Note: Accessors of a Shared Variable do not actually pass information to one another directly, but instead pass and receive data via a server, the Shared Variable Engine.
Shared Variable accessors come in two forms.
Publisher: A publisher, or writer, can change the current value of a Shared Variable. When a publisher is written to, it has the following interaction with the SVE that is hosting the publisher’s Shared Variable:
1. The publisher requests the SVE to make a value change to the Shared Variable.
2. The SVE checks the publisher’s domain access privileges and allows the publisher to change the value of the Shared Variable.
3. The publisher publishes a new value to the Shared Variable.
4. The Shared Variable Engine notifies all subscribing accessors of the change.
Writing to a publisher does not guarantee an update because the NI-PSP is lossy. Buffering can prevent some data loss, but it does not make the protocol truly lossless.
Subscriber: A subscriber, or reader, can output the latest value of a Shared Variable. A subscriber does not make requests to the SVE to obtain the latest value of a Shared Variable. Instead, the SVE notifies the subscriber when a value, timestamp, status or other aspect of a Shared Variable has changed. A subscriber will always return the most recent value for a variable, if it has no other values in its buffer.
Some accessors can be publishers and subscribers at the same time. The DataSocket and programmatic Shared Variable APIs can have multiple read and write nodes connected with a single reference.
Server side buffer: You configure this buffer in the Network page of the Shared Variable Properties dialog box. Although this buffer resides on the server, the SVE does not create it until the first subscription request from a client is received; therefore, the SVE will not buffer updates when there are no accessors listening. New subscriptions only receive the latest buffered value when connecting even if another subscription has already initialized the buffer. Items are added to this buffer when we publish Shared Variable data from an accessor. The SVE empties the buffer as quickly as possible and is designed to accommodate bursts of writes to prevent data loss. The SVE destroys the server side buffer when the last accessor is unsubscribed.
The server side buffer will always be the same size as the accessor side buffer when using Shared Variable Static Nodes. The same is not true for APIs such as DataSocket and programmatic Shared Variable because we can define the size of the accessor side buffer dynamically.
NI-PSP Client (NPC): The NPC is responsible for maintaining and operating all the Accessor Side buffers and Views for subscribers on a single machine. The NPC also communicates with remote SVEs for publishers on a single machine. On Windows the NPC is installed with the SVE. The same is true in LabVIEW Real-Time (RT) if you install the Network Variable Engine component on an RT target. You also have the option of installing the NPC stand-alone from the SVE with the Variable Client Support for LabVIEW Real-Time component. With this configuration an RT target cannot host Shared Variables, but it can still publish and subscribe to Shared Variables while using less memory and CPU resources on the RT target. The NPC exists for each application instance accessing Shared Variables. Therefore, on Windows it’s possible to have several NPCs operating simultaneously. On RT there is only one application instance; therefore, there is only one instance of the NPC.
Accessor side buffer: This is the buffer responsible for maintaining the queue of values for all accessors of a Shared Variable per application. It is this buffer that insulates your Shared Variable accessors from fluctuations in loop speed or network traffic. The NPC removes values from this buffer when the buffer overflows. Undeploying a Shared Variable does not destroy the accessor side buffer; however, the Shared Variable accessor will return bad quality errors.
Applications that can access a Shared Variable include, LabVIEW, Distributed System Manager, stand-alone Real-Time applications (rtexe), and stand-alone Windows applications.
The accessor side buffer size is a property of the accessor connection and is established when a subscriber comes online. This property is set at edit time for Static Shared Variable nodes in the Shared Variable properties dialog window. For the DataSocket APIs this property is set at run-time via the DataSocket BufferMaxPackets property node. For the programmatic Shared Variable this property is set by the Open and Verify Variable Connection and Open Variable Connection in Background VIs; therefore to change the buffer size at runtime the calling VI must first close and then reopen the connection.
For example, in the diagram bellow, a Shared Variable is hosted on a Windows PC -- running Distributed System manager and a LabVIEW VI -- and two cRIOs, each running stand-alone Real-Time applications. In this case each machine and application is accessing the same Shared Variable. Each of these machines runs an application with one or more subscribing accessors. Here, the Windows machine will have two accessor side buffers (one for LabVIEW and one for Distributed System Manager), and each cRIO will have a single accessor side buffer.
Figure 1: The hierarchy of the Shared Variable Engine, Accessor side buffers, and Shared Variable Accessors accessing a single Shared Variable. Each color represents a single machine with applications accessing the same Shared Variable.
View: A View is sometimes referred to as a Shared Variable read buffer in the LabVIEW help. We will use the term “View” to avoid confusion with the actual buffers in the system. A View is not a programming construct, but rather a concept used to describe Shared Variable behavior. The same physical buffer (accessor side buffer) is used by all accessors where each accessor maintains its own index into the buffer. The behavior of this “index into the buffer” is described here as a View.
A View can be thought of as the first-in, first-out (FIFO) buffer associated with a unique accessor. Each accessor will have its own View, and the items in this View have the same value and relative order as the items in the accessor side buffer. Unlike the accessor side buffer, the NPC removes values from an accessor’s View when the accessor is read as well as when it is overflowed. An accessor’s View cannot be larger than its associated accessor side buffer. A View is destroyed when you undeploy the SV or the accessor leaves memory. If a View contains a single value, this value will be output by the subscribing accessor each time the accessor is read.
LabVIEW APIs for Accessing Shared Variables
Static Shared Variable Node: This is the node that is most commonly thought of when describing a Shared Variable. You can only configure the static node through the LabVIEW project. The static node supports blocking reads. Each instance of a Shared Variable node on a block diagram is an individual accessor regardless of whether these nodes are accessing a single Shared Variable or multiple Shared Variables.
Figure 2: Shared Variable Static Nodes
Programmatic Shared Variable API: This API, introduced in LabVIEW 2009, allows you to read and write Shared Variable and other PSP items and IOVs using a run time API. This method allows you to dynamically determine which Shared Variables to read and write at run time. The Shared Variable Dynamic API does not support accessor side buffering in LabVIEW 2009, but it does in LabVIEW 2010. All programmatic Shared Variable VIs sharing a single reference wire constitute a single accessor.
Figure 3: Programmatic Shared Variable API
DataSocket API: DataSocket is a network API that can access a variety of different network protocols, including NI-PSP. All DataSocket VIs sharing a single reference wire constitute a single accessor.
Figure 4: DataSocket API
DSC Tag API: The Tag API utilizes LabVIEW Object Oriented Programming (LVOOP) and was designed to efficiently access and manage a large number of Shared Variables. The Tag API can access a limited number of data types compared to the programmatic Shared Variable and DataSocket APIs. The Tag API can also read Citadel trace data for a Shared Variable, as well as read and acknowledge Shared Variable alarms. All Tag API VIs sharing a single reference wire constitute a single accessor.
Figure 5: DSC Tag API
DSC Event Structure API: The Event Structure API allows for dynamic user events to be generated when a registered Shared Variable changes values. This API is convenient when automating a user interface. By default, the Event Structure API does not access values within an accessor side buffer. To do this, you must wire a value to the updates to buffer (no buffer) input on the Request Value Change Notifications VI. The Event Structure API is only available when you have the LabVIEW DSC module. When you use the Event structure to access Shared Variable data, accessors are created when user events are registered with the shared variable value change notification refnum from the Request Value Changes VI.
Figure 6: DSC Event Structure API