Functional programming, reactive programming that provide us a different thinking and means for dealing the real world problems comparing to object oriented(OO) programming. As we known, OO provide us good flow for handling synchronous data and interactivity between objects. But sometimes for communication/coordination under asynchronous environment, reactive programming give us a more abstract level and efficiency ways(lock free).
Assume that we have monitoring center that manage a group of device(s) across different area/zone on network. Each device would dynamic join/leave the group for any reasons, the center would like to control(manage) and monitor stat of each device(s).
As above picture show that monitoring center will manage below device(s) from different action/behavior. For example, keeping alive, sending alarm event(s), notice messaging…etc.
How to solve using AKKA.Net framework
AKKA has introduced the actor model that passing the event(s) across tree hierarchy. With children-parent relationship make it easily to control each nodes status and handle fault/crash recovering. That’s start initial the management node(from server) and assume that the devices(on client) might join/leave the entire monitor system dynamically. Our project structure as below:
Buildup actor system through AKKA configuration setting(hocon): akkaConfig.xml. Inside the system, create actor: InputActor for handling user input interactivity. Create another actor: SenderActor for processing the communication between clients, the initial stat would be waiting client to register.
// Server entry point
static void Main(string args)
var builder = new ConfigurationBuilder()
Configuration = builder.Build(); var config =
using (var actorSys =
var inputActor = actorSys.ActorOf(Props.Create<InputActor>(), "Input");
var senderActor = actorSys.ActorOf(Props.Create<AlarmSenderActor>(inputActor), Constants.ALARM_SENDER_NAME); Message cmd = new Message()
Type = MessageType.ServerWaitSubscribe
Configuration over AKKA.Net not support dependency injection for .Net core, so we used xml file instead and parsing source string as workaround.
<?xml version="1.0" encoding="utf-8" ?>
# here we are configuring log levels
log-config-on-start = off
stdout-loglevel = INFO
loglevel = ERROR
# this config section will be referenced as akka.actor
provider = "Akka.Remote.RemoteActorRefProvider,
receive = on
autoreceive = on
lifecycle = on
event-stream = on
unhandled = on
# here we're configuring the Akka.Remote module
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
#applied-adapters = 
transport-protocol = tcp
port = 8091
hostname = ""
public-hostname = "public.domain.address"
log-remote-lifecycle-events = INFO
hostname: left blank might dynamically assign host for the actor system
pubic-hostname: useful while you deploy application inside the docker environment
Startup from new actor system (initial with client side configuration). Inside the system, create actor: AlarmReceiverActor for subscription to server, after connection setup, bidirectional communication would be available.
// Client entry point
static void Main(string args)
// load the configuration xml
using (var actorSys = ActorSystem.Create(Constants.ALARM_ACTOR_CLIENT_SYS, config))
Guid subscriberGuid = Guid.NewGuid();
var receiverActor =
actorSys.ActorOf(Props.Create<AlarmReceiverActor>(), string.Format(Constants.ALARM_RECEIVER_NAME, subscriberGuid.ToString()));
Thread.Sleep(2000); // let user know the terminate notice message
// we could access/communicate the server actor via below snippet code
var senderActor = Context.ActorSelection("akka.tcp://ALARM_ACTOR_SRV_SYS@public.domain .address:8091/user/Sender"); // then send message to actor
public.domain.address: same address value inside the section *remote:public-host* (akkaConfig.xml) over the sever side
Let’s start the server process first then initialize one client. Server will keep waiting for client to register. While once client(at least one) got subscribed, the server turned into command mode.
Server Begun communication with client via sending alarm message, testing message and terminate message.
Client received the message immediately.
Registered another client.
Sent new alarm message to both client(broadcast).
Finally, sent the terminate message to all clients(broadcast).