I have a distributed system of actors, some on Windows, and some on Linux machine. Sometimes one actor may need to connect other actor and make some communications. Of course, there are cases when one of them is on Windows, and other is on Linux system.
Actors connect each other via ActorSelection. There problem is, that when Windows actor is trying to communicate with Linux one, all works fine. But when Linux actor initiating communication, the ActorSelection.ResolveOne failes.
I've made a little sample here:
static void Main(string[] args)
{
ActorSystem system = ActorSystem.Create("TestSystem");
system.ActorOf(Props.Create(() => new ConnectActor()), "test");
while (true)
{
var address = Console.ReadLine();
if (string.IsNullOrEmpty(address))
{
system.Terminate();
return;
}
var remoteAddress = $"akka.tcp://{system.Name}@{address}/user/test";
try
{
var actor = system.ActorSelection(remoteAddress).ResolveOne(TimeSpan.FromMilliseconds(5000)).Result;
Console.WriteLine("Resolved: " + actor.Path);
}
catch (Exception ex)
{
Console.WriteLine("Failed: " + ex.Message);
}
}
}
Configuration in app.config is the following:
akka {
loggers = ["Akka.Logger.NLog.NLogLogger, Akka.Logger.NLog"]
suppress-json-serializer-warning = on
loglevel = "DEBUG"
log-config-on-start = on
actor {
provider = "Akka.Remote.RemoteActorRefProvider, Akka.Remote"
debug {
receive = on
autoreceive = on
lifecycle = on
event-stream = on
unhandled = on
}
}
remote {
log-remote-lifecycle-events = DEBUG
log-received-messages = on
helios.tcp {
transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
transport-protocol = tcp
applied-adapters = []
port = 9000
hostname = "0.0.0.0"
public-hostname = "192.168.0.251" // This is different for different hosts, of course
}
}
}
The public-hostname is publicly available ip address.
So, here are the cases:
- When running Windows/Windows, both instances see each other (I give them remote address - they output "Resolved ")
- When running Windows/Linux, and give linux actor's address to windows actor, it outputs "Resolved". So windows connects linux with no problem. After that giving windows actor's address to linux actor also gives "Resolved" - I suppose, the connection is already established and there is no real handshakes passing
- BUT when running Windiws/Linux and give windows actor's address to linux actor, it gives "Failed". No messages about any errors or dropping packages. At the end of the log there is the following:
Akka.Remote.Transport.AkkaProtocolManager|now supervising akka://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0.252%5D%3A36983-1|||| 13:20:08.3766|DEBUGAkka.Remote.Transport.ProtocolStateActor|Started (Akka.Remote.Transport.ProtocolStateActor)|||| 13:20:08.3922|DEBUG|Akka.Remote.Transport.ProtocolStateActor|Stopped||||
The issue with similar logs is described here: Akka.net starting and stopping with no activity The reason there is that system protocols are not compatible. Is this the same issue? As I got from Akka.NET docs and release notes, it has full linux support...
So, am I missing something in configuration? Can anybody make this sample work with Linux -> Windows connection?