Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Remote Actors for .NET and Mono
C# Smalltalk
branch: master

README.md

Remote Actors for .NET

Remact.Net facilitates the development of remote actors in .NET languages.

It is a class library written in C-Sharp.
It runs in Microsoft .NET and Linux-Mono environments.

The Actor model is inspired by physics and by nature.
It brings order to multithread, multicore, multihost systems.
These days many systems have such requirements. The Reactive Manifesto explains it in detail.

Industrial control systems with dynamically connected and movable intelligent subsystems have been in focus of Remact.Net's design.
Therefore, this library supports many instances of the same application running on one or on distributed hosts.
It also supports dynamic discovery of actors and does not require configuration of host names and TCP ports.

In spite of all these features, Remact.Net is remarkably slim and easy to adapt for special needs.

Project status

Remact.Net is in good shape now. You are invited to try it out.

The next development steps will be:

  • Xamarin.Android test application
  • Additional integration tests for bidirectional communication
  • Do not use Type.AssemblyQualifiedTypeName for dispatching
  • Extract Remact.Msgpack to reduce dependencies and deployment size
  • Port unit tests from AsyncWcfLib
  • Integrate Newtonsoft logging
  • Cleanup TODO's

Feature list

The following goals have been reached:

  • Small and clean API allows to dynamically create lightweight actors
  • Local actors (message passing between threads)
  • Remote actors (message passing between hosts or processes)
  • WebSockets, Json and other open standards are used to link Remact actors
  • Supported protocols: WAMP or JSON-RPC.
  • Supported serialization: Json or MsgPack (binary).
  • Peer to peer communication using distributed actor catalogs avoid single point of failure
  • Fully support bidirectional models: client-server / server-client / publish-subscribe
  • Strongly typed interfaces
  • High throughput on Linux and Windows: More than 5000 request/respose pairs per second between processes. Remact.Net is much faster on Linux and much more interoperable than its predecessor AsyncWcfLib.

Related work

The Robot Operating System ROS is a popular framework that uses the actor model. There, a new messaging subsystem DDS is considered.

Some programming languages have built-in support for remote actors:

For other languages there are libraries to help programming remote actors:

Serialization is still an evolving theme. I'm looking for a simple solution for interoperable, binary serialization that supports inheritance and extensibility (lax versioning). Interesting developments are:

Dependencies and standards

Remact.Net is built on open standards and uses open source components. I would like to thank all who built these components for their contribution to the open source community.

Documentation

High level design

On a high level a Remact system is split in three parts:

  • Contracts: Shared interfaces and data structures are delivered in their own assembly. The datastructures may have a dependency to Nowtonsoft.Json because of serialization attributes. The interfaces currently do have a dependency to Remact.Net.RemactMessage.

  • Actors: Actors use contracts to communicate. Actors do not have a direct dependency to other actors. An actor is programmed without having to know its location in the system.

  • System wiring: This third part of the system places the actor into its location during runtime. It defines the process and the host to run on. It also connects client and service ports of the actors. The wiring may use dynamic features like actor location at runtime, m:n relationship and backup actors.

Conceptual parts

Actors and ports

Think of an actor as a room with several ports.
Only one person - the worker - is walking (running) around in the room and handles all stored goods. The worker also sends packets out through the ports or gets packets sent in through the ports.

In software, the actor is a group of objects that are accessed by one worker thread only. Data inside an actor is as consistant as the incoming events allow it to be. No other threads may access the objects of an actor, therefore the actor itself has no critical sections (locks).

The actor has ports. These are linked to other actors on the same or on a remote process.
All incoming events are received as messages passed through one of the ports. The actor has one message queue that queues all incoming messages (requests, responses, notifications or errors).

Client ports

A client port is built of a RemactPortProxy that is connected to a RemactPortService of another actor.
Messages are sent by the actor to the proxy of the connected service port. Sending is a non blocking operation.
Optionally the remote actor may send a reply message. It is handled as an asynchronous callback event
in a lambda expression or in a task continuation of the origin actor.
Contrary to the normal client/server pattern, the service port may send notification and request messages to a client. These messages are handled in a method defined by the contract interface.
Disconnecting the client is signaled to the service. A disconnect signal may also be issued by the service.

Service ports

Many remote client ports may be connected to one service port.
Once connected, messages may be sent from the client to the service but also from the service to the client.
Address and version information for each connected client is available for the service.
Additional session data may be kept for each connection on service and/or client side.
Periodic messages should be exchanged by the actors to check the communication channels.

RemactMessage and Payload

The RemactMessage class addresses source and destination ports. It is used to route the payload data through the system.
The payload may be of any serializable object type.
By default serialization is done by Newtonsoft.Json. Therefore, attributes like [JsonProperty] and [JsonIgnore] may be used to control the serialization process.
Other serializers like msgpack-cli or a dynamic switching serializer are pluggable. The folder Remact.Net.Protocol contains the currently implemented combinations of protocols and serializers.

Methods

Messages are sent to the method that handles the message payload type as a single input parameter.
The method also defines the reply payload as the return type.
A void method will normally not reply a message.
But in case of error or exception, also void methods will reply an ErrorMessage.

Contract interface

A contract interface defines the set of methods and the corresponding request and response message types that are available on a certain client or service port.
On the receiving side the methods will have the specified, single message payload parameter and additional parameters for message source identification and session data.

The folder src/Remact.Net/Contracts and test/SpeedTestApp/src/Contracts contains interfaces for remotely callable methods and their corresponding request- and response messages. These definitions and their XML comments form the basic interface definition of actors.

These contracts must be present on both sides of the communication channel. For actors not written in a .NET programming language (e.g. Java Script), the interface contract must be translated.

Remact.Catalog application

Remact.Catalog is an application containing the catalog actor. The catalog is informed about all Remact service ports in a network.
The catalog knows all coordinates like service name, version, host and TCP portnumber.
The catalog actor synchronizes itself with partner catalog actors on other hosts.

Normally each host runs a catalog actor. To add a new host into a Remact network, just reference a running catalog host. Then, all actors including those on the new host are informed about the status of all Remact service ports.
The catalog actor is for actors what a DNS server is for hosts.

Anonymous client applications

Applications that have only client functionality can run in a browser (using Java Script) or as a .NET application. These applications are not registered in the catalog but they can use a catalog actor to get coordinates of open service ports.

Communication models

Client / Service

One actor may contain several clients and services.
The output (client) sends a request to the input (service) of another actor and will get the reply from it.

Notifications

The service port may send a callback notification to the client port.
Also, the client port may send a notification to the service port.
Notifications are defined as parameter of a void method of the receiving port contract interface.
There is no reply message to notifications.

Service / Client

In Remact, communication is symmetrical. Therefore services may also send requests to a method of the connected client port and get a response from it. The difference between service and client lies in the 1 : many relationship
and in the active part the client is playing during connection buildup.

Publish / Subscribe

A service port can send messages to all its connected client ports.
Connecting to such a service in fact means - subscribing to its publications.
The publisher knows who received its publications because all communication is done through reliable
TCP connections to known partners.

Communication stack

Remact uses the following layers when receiving a message from a remote actor:

  • The .NET TCP layer raises an event on a threadpool thread
  • The Alchemy.WebSocketClient or -Service interpretes the data frame and dispatches it to the protocol layer
  • The Wamp- or Json.RPC protocol layer deserializes the payload to a Newtonsoft.Json.Linq.JToken
  • The RemactClient or -Service switches to the correct actor thread, builds a RemactMessage and and handles Remact internal messages
  • User messages are handled by the RemactDispatcher. It finds the addressed method name in the list of supported contract interfaces, it converts the payload to the .NET type defined as first parameter of the addressed method and invokes the addressed method by passing the strong typed payload, the RemactMessage and the session data as parameters
  • The called method may accept any serializable payload type, a Newtonsoft.Json.Linq.JToken or a dynamic object
  • When the addressed method could not be found or the received stream could not be converted to the correct .NET type, a default message handler is called
  • The protocol layer serializes the return type of the called method and sends it as a response

Assemblies

  • Remact.Net.dll: The remote actors library. It has dependencies to Alchemy and Newtonsoft.Json.
  • Remact.Catalog.exe: The remact catalog application for desktop systems.
  • Remact.DesktopApp.dll: A helper library for desktop systems.

How to build and test Remact.Net

You have to clone these (small) repos to be able to build:

  $ git clone https://github.com/steforster/Remact.Net.git  
  $ git clone https://github.com/steforster/Alchemy-Websockets.git  
  $ git clone https://github.com/JamesNK/Newtonsoft.Json.git  
  $ git clone https://github.com/Code-Sharp/Newtonsoft.Msgpack.git  
  $ git clone https://github.com/msgpack/msgpack-cli.git  

Afterwards your git project folder should look like this:

  $ ls  
  Alchemy-Websockets  msgpack-cli  Newtonsoft.Json  Newtonsoft.MsgPack  Remact.Net  ...  

The Remact.VS2015 solution is used for VisualStudio 2015 under Windows.
Use Remact.Mono.sln for earlier VS versions and for MonoDevelop 4.0.12 under Ubuntu 14.04.

Both solutions currently reference the same projects, target the Mono/.NET 4.0 frameworks and generate their output into a 'Mono' folder.

To test under Windows you may start "test\SpeedTestApp\Mono_startTest2.cmd",
under Ubuntu you may start "test\SpeedTestApp\Mono_startTest2.sh".

License

Remact.Net is licensed under MIT. Copyright (c) 2014-2015, Stefan Forster.

Something went wrong with that request. Please try again.