我有一个分布式演员系统,一些在 Windows 上,一些在 Linux 机器上。有时一个参与者可能需要连接其他参与者并进行一些通信。当然,也有其中一种在Windows系统上,另一种在Linux系统上的情况。
Actor 通过 ActorSelection 相互连接。问题是,当 Windows actor 尝试与 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 地址。
所以,这里是案例:
Akka.Remote.Transport.AkkaProtocolManager|现在监督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|开始(Akka.Remote.Transport.ProtocolStateActor)|||| 13:20:08.3922|调试|Akka.Remote.Transport.ProtocolStateActor|停止||||
这里描述了类似日志的问题:Akka.net 在没有活动 的情况下启动和停止原因是系统协议不兼容。这是同样的问题吗?正如我从 Akka.NET 文档和发行说明中获得的,它具有完整的 linux 支持...
那么,我在配置中遗漏了什么吗?任何人都可以将此示例与 Linux -> Windows 连接一起使用吗?
这里的问题似乎是 Mono 由于某种原因在其绑定地址中使用映射到 IPV4 的 IPV6 地址。
akka://TestSystem/system/transports/akkaprotocolmanager.tcp.0/akkaProtocol-tcp%3A%2F%2FTestSystem%40%5B%3A%3Affff%3A192.168.0.252%5D%3A36983-1
如果你解码这个 URL,它会被翻译成
akkaProtocol-tcp://TestSystem@[::ffff:192.168.0.252]:36983-
所以我认为这里发生的事情是 Helios 应该解析的出站地址在 Linux 端被搞砸了,所以它尝试连接到一个格式错误的地址,该地址与 Windows 侦听的地址不同。我怀疑参与者选择 URI 解析代码中特定于平台的内容不正确。
我在这里提交了一个错误:https://github.com/akkadotnet/akka.net/issues/2254
| 归档时间: | 
 | 
| 查看次数: | 606 次 | 
| 最近记录: |