Linux和Windows之间的Akka.NET Remote

时间:2016-08-12 12:22:48

标签: c# linux akka.net

我有一个分布式的演员系统,一些在Windows上,一些在Linux机器上。有时一个演员可能需要连接其他演员并进行一些沟通。当然,有些情况下,其中一个在Windows上,另一个在Linux系统上。

演员通过ActorSelection相互连接。问题是,当Windows演员试图与Linux通信时,一切正常。但是当Linux actor发起通信时,ActorSelection.ResolveOne就会失败。

我在这里做了一些示例:

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);
            }
        }
}

app.config中的配置如下:

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
            }
         }
      }

public-hostname是公共可用的ip地址。

所以,以下是案例:

  • 运行Windows / Windows时,两个实例互相看到(我给他们远程地址 - 他们输出“已解决”)
  • 当运行Windows / Linux,并将linux actor的地址提供给windows actor时,它输出“Resolved”。所以Windows连接linux没有问题。之后给windows演员的地址给linux演员也给了“Resolved” - 我想,连接已经建立并且没有真正的握手传递
  • 但是当运行Windiws / Linux并将windows actor的地址提供给linux actor时,它会给出“失败”。没有关于任何错误或丢弃包的消息。在日志的末尾有以下内容:
  

Akka.Remote.Transport.AkkaProtocolManager |现在监督akka://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0 0.252%5D%3A36983-1 ||||   13:20:08.3766 | DEBUGAkka.Remote.Transport.ProtocolStateActor |已启动(Akka.Remote.Transport.ProtocolStateActor)||||   13:20:08.3922 | DEBUG | Akka.Remote.Transport.ProtocolStateActor | ||||停止

此处描述了类似日志的问题:Akka.net starting and stopping with no activity 原因是系统协议不兼容。这是同一个问题吗?正如我从Akka.NET文档和发行说明中得到的那样,它有完整的Linux支持......

那么,我在配置中遗漏了什么吗?任何人都可以使这个样本与Linux一起工作 - > Windows连接?

1 个答案:

答案 0 :(得分:1)

这里的问题似乎是Mono出于某种原因使用映射到绑定地址的IPV4的IPV6地址。

  

阿卡://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0.252%5D%3A36983-1

如果您解码此转换为

的网址
  

akkaProtocol-TCP:// TestSystem @ [:: FFFF:192.168.0.252]:36983-

所以我认为这里发生的事情是Helios应该解析的出站地址已经搞砸了Linux端,所以它试图连接到一个不正常的地址,它与一个Windows监听。我怀疑,在actor选择URI解析代码中特定于平台的东西是不正确的。

我在此处提交了一个错误:https://github.com/akkadotnet/akka.net/issues/2254