Network Endpoints allow you to link two actors running in separate application instances.
Update (8/24/21): Version 3.0 has been released! Get it from the NI Tools Network repository in VI Package Manager. See below for release notes.
I am working on version 4.0, which will take advantage of interfaces.
Network Endpoints manage a Message Stream. Message Stream is an abstract class that defines an API for transmitting Actor Framework messages between applications. Children of this class adapt specific protocols, like TCP/IP or Network Streams to the API. Message Streams will transmit and receive any message class. Message Streams are described in more detail later in this document.
Use Write Message Stream.vi to specify the Message Stream that will be used for the connection. You must set this value prior to launching the actor.
Network Endpoint is an abstract class. Use Nested Endpoint or Caller Endpoint in applications.
To use a network endpoint (Caller or Nested), place an endpoint constant on the block diagram. Use Write Message Stream.vi to set the instance of Message Stream to use for the session. Launch the network endpoint. The endpoint will attempt to connect to its remote counterpart. If the connection times out, the launch attempt will fail. If connection is established, the endpoint will run until it receives a Stop message; it will break the network connection and return Last Ack to its caller. An endpoint will also stop automatically if its remote connection is broken.
Use Write timeout.vi to set the amount of time the actor will wait while attempting to create an endpoint (i.e. while waiting for a connection). If this value is too small, you may experience difficulty obtaining a connection. If it is too large, you may observe a delay when attempting to stop the actor. You must set this value prior to launching the actor.
Network Endpoints have no message classes of their own; you can send any message class to an endpoint. Stop and Last Ack are handled locally; anything else is forwarded to the remote endpoint.
A Nested Endpoint is a Network Endpoint that is launched by a calling actor. The nested endpoint will forward messages it receives from its caller across the network. Any message the nested endpoint receives from across the network will be passed up to its caller.
When used with a remote nested endpoint, the endpoints establish a sibling relationship between the actors.
When used with a remote Caller Endpoint, the endpoints establish a caller-nested relationship between the actors.
Nested Endpoints send a Connected Msg to their callers when they successfully connect to a remote endpoint (of any type). Connected messages are abstract; the caller must provide the actual implementation to be used. The payload of a Connected message is the nested endpoint’s enqueuer; use this data when you are using multiple nested endpoints, and need to identify which endpoint has successfully connected.
Use Write Connected Msg.vi to set a concrete implementation of Connected Msg to send to the caller.
A Caller Endpoint is a Network Endpoint that sits at the top of an actor tree. Caller endpoints launch a single nested actor that you specify. If a remote actor uses a nested endpoint to connect to a local caller endpoint, the caller endpoint's nested actor will act like a nested actor of the remote actor. Any messages sent from the nested actor to its caller will be forwarded across the network connection. Any messages received from across the network by the caller endpoint will be passed down to the nested actor.
If Caller Endpoint receives a Last Ack from its nested actor, it will forward the Last Ack across the network. Note that, due to restrictions in the Actor Framework API, the priority of the Last Ack message will be downgraded from Critical to High. The Caller Endpoint will remain active; it is the responsibility of the calling application to destroy it.
Very little work has been done with Caller Endpoints, and they should be considered experimental.
Use Read/Write Nested Actor.vi to get or set the nested actor called by the Caller Endpoint.
Message Streams transmit Actor Framework messages between applications. Children of the class implement specific protocols. Message Streams for TCP/IP and Network Streams are included in the Network Endpoint Actors package.
The API requires that one endpoint be the initiator, and the other the listener. To reflect this, each protocol is implemented as a pair of classes, Initiator and Listener. Passing an instance of TCP Stream Initiator to a network endpoint means the endpoint will attempt to connect to another endpoint. Passing an instance of TCP Stream Listener to a network endpoint means the endpoint will wait passively for a connection. In either case, if no connection is made within the timeout period, the endpoint will shut down and return an error.
Both Initiator and Listener classes include a Create method. Create methods take address information as inputs, and return a Message Stream object.
Message Streams can accept a Cipher plug-in, which you can use to encrypt/decrypt transmitted messages. Cipher is an abstract class; inherit from this class to add specific ciphers to your application. No ciphers are included in the Network Endpoint Actors package.
How Network Endpoint Actors Differ from the Linked Network Actor
Network endpoints do not persist between connections, meaning that a network endpoint actor will stop itself if it fails to connect to a remote endpoint, or if the remote endpoint ends the connection. Linked network actors persist between connections - when the remote disconnects, the LNA will wait for a new connection. It should be a straightforward task to build a version of the Linked Network Actor that uses network endpoints; such an implementation would better adhere to the Single Responsibility Principle.
LNAs currently only support network streams, whereas network endpoints can also use TCP/IP, or any other protocol you wish to implement. Network streams also have some support for encryption extensions.
Finally, LNAs require you to do extra work to package a message for transmission, i.e. you have to send your message to the LNA for forwarding via a Transmit Message. Network endpoints make use of an override of the Receive Message.vi method to make transmission transparent.
As with LNAs, you will need to wrap your network endpoints in some form of proxy class to manage library locking.
About the Packages
The latest version of the Network Endpoint Actors is available on VIPM.
The attached files below are VI Package Configurations, and include the base package and an example. The versions are nearly identical, except that the 2015 version includes DETT (Desktop Execution Trace Toolkit) support.
Update (1/7/16): Many of you want to use Network Endpoints to create client-server architectures, where the remote client is only intermittently connected. Since the endpoints are single-use (the actors stop when you break the connection), several people have enquired about the best way to restart the server-side endpoint. Here is the simplest way to have your server detect that its endpoint has terminated and restart it.
When the server endpoint terminates, it will send its caller a Last Ack message. Use this fact.
1. In the caller, create an override of Handle Last Ack Core.vi.
2. In Handle Last Ack Core, use the Read Actor method of Last Ack to get the nested endpoint actor.
3. Relaunch the endpoint using Launch Nested Actor.vi
4. Save the endpoint enqueuer for later use.
Here is a block diagram illustrating the concept:
Intelligent use of overrides of Handle Last Ack Core can do truly amazing things for your code.
Version 3.0 Release Notes:
This package is now licensed under the Apache License, Version 2.0.
I replaced (the non-reentrant) General Error Handler.vi in Network Endpoint:Receive Message.vi with (the reentrant) Clear Errors.vi
Users may now specify the local IP address to use with a TCP Stream Listener, which enables support for multiple NICs.
I have wrapped the flatten/unflatten functionality in TCP Stream Send Message.vi and Receive Message.vi in a class, called the Message Flattener. Users can override Message Flattener to support different flattening schemes. Among other things, this is useful when sending messages to non-AF or non-LabVIEW environments. Message Flattener also includes an override method, called Swap Endianness, to allow the user to change the Endianness of the packet size value. By default, it is little-endian, but some non-LabVIEW systems may require this value to be big-endian.
The packet size is now sent with a separate TCP Write, which eliminates a potentially large memory copy on the block diagram.
This release fixes a bug where the Register Actor message (part of the AF Debug system) was being forwarded to the remote connection. This would result in incorrect reporting in the remote's DETT traces.
The Register Actor message was introduced in LV 2017, hence the version bump. However, the implementation can be back ported to 2015 or 2016, if required.