如何从actor内部获取绝对远程actor url?

时间:2013-01-11 23:03:00

标签: scala akka

我想做这样的事情。

演员A:

    actorB ! "info"

     def receive()={
     case _ => {
          println("Remote address is "+ _)

        }
}

演员B :(远程部署)

def receive()={
 case "info" => {
      sender tell self.path.address.toString

    }

}

我想让它返回字符串akka://10.4.20.40:2555 / slave / user / slaverunner。但我得到的只是akka://奴隶。如何获取远程主机和端口? 。地址对象上的属性host,port和hostport不返回任何内容

4 个答案:

答案 0 :(得分:7)

如果你打电话

sender.path.toString

在演员A中,您将获得发件人的地址。因此,只要您可以向其发送消息,就不需要将地址传递给另一个actor系统。

Akka不会为本地系统中的演员提供远程路径,这就是演员B中的self.path.address.toString无效的原因。

如果您确实要将主机和端口从B发送到A,那么您需要通过RemoteActorRefProvider访问ExtendedActorSystem。正式的方法是通过Extension。例如:

class MyExtensionImpl(system: ExtendedActorSystem) extends Extension {
  def address = system.provider match {
    case rarp: RemoteActorRefProvider => rarp.transport.address
    case _ => system.provider.rootPath.address
  }
}

object MyExtension extends ExtensionKey[MyExtensionImpl]

val address = MyExtension(system).address

这将为您提供与B远程通信所需的确切地址。

(请注意,此代码适用于Akka 2.0.x.在2.1.x中,您可以使用RemoteActorRefProvider避免浏览system.provider.getDefaultAddress

在Akka中如果您使用构造actor地址以便与actorFor一起使用,那么您需要确保主机名完全匹配。

例如,如果ActorSystem认为主机是foo.bar.com,那么它将忽略远程主机发送给actorFor("akka://slave@foo:2555/user/slaverunner")的消息

答案 1 :(得分:2)

对于最近的akka​​版本(2.1+),请使用:

class RemoteAddressExtensionImpl(system: ExtendedActorSystem) extends Extension {
  def address = system.provider.getDefaultAddress
}

object RemoteAddressExtension extends ExtensionKey[RemoteAddressExtensionImpl]

val remoteAddr = RemoteAddressExtension(context.system).address
val remotePath = self.path.toStringWithAddress(remoteAddr))

您正在寻找remotePath:

  

我希望它能给我回复字符串   阿卡://10.4.20.40:2555 /从/用户/ slaverunner

对于最近的akka​​版本(2.5.3),请使用:

class RemoteAddressExtensionImpl(system: ExtendedActorSystem) extends Extension {
  def address = system.provider.getDefaultAddress
}

object RemoteAddressExtension extends ExtensionId[RemoteAddressExtensionImpl]
with ExtensionIdProvider {
  override def lookup = RemoteAddressExtension
  override def createExtension(system: ExtendedActorSystem) = new RemoteAddressExtensionImpl(system)
  override def get(system: ActorSystem): RemoteAddressExtensionImpl = super.get(system)
}

答案 2 :(得分:1)

我把它包裹String

 ConfigString("akka://serversys@127.0.0.1:2552")

使用system.settings

context.system.settings.config.getValue("akka.actor.deployment.\"/root\".remote")

演员是一个“根”演员,在Viktor Klang在关于“确定演员是否已经死亡”的邮件小组讨论中提出的结构方案中。它是这样创建的:

lazy val rootActor = actorSystem.actorOf(Props[Root], "root")
来自ActorSystem

是这样创建的:

lazy val actorSystem = ActorSystem("serversys", ConfigFactory.parseString(""" 
akka {
  loglevel = "DEBUG"
  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }
  remote {
    transport = "akka.remote.netty.NettyRemoteTransport"
  }
}
serverconf {
  include "common"
  akka {
    actor {
      deployment {
        /root {
          remote = "akka://serversys@127.0.0.1:2552"
        }    
      }
    }
    remote {
      netty {
        hostname = "127.0.0.1"
        port = 2552
      }
    }
  }
}
""").getConfig("serverconf"))

使用Akka 2.0.3在Scala 2.9.2 REPL中测试,我仍在使用。

使用Config文档解压实际值:http://typesafehub.github.com/config/v0.3.0/

答案 3 :(得分:1)

public address of an actorsystem。 阅读完整的讨论,并注意“通常”您不需要抓住主机/端口。