How do I get the absolute remote actor url from in

2019-03-19 08:16发布

问题:

I want to do do something like this .

Actor A :

    actorB ! "info"

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

        }
}

Actor B : (this deployed remotely )

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

    }

}

I want it to return me the string akka://10.4.20.40:2555/slave/user/slaverunner . But what I get is just akka://slave. How do I get the remote host and port? . The properties host,port and hostport on the address object dont return anything

回答1:

If you call

sender.path.toString

in actor A you will get the address of the sender. So you don't need to pass the address to another actor system as long as you can send a message to it.

Akka will not give you a remote path for an actor in the local system, which is why self.path.address.toString in actor B won't work.

If you really want to send the host and port from B to A then you'll need to get access to a RemoteActorRefProvider via the ExtendedActorSystem. The official way to do that is through an Extension. For example:

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

And that will give you the exact address that you need to communicate remotely with B.

(note this code works with Akka 2.0.x. In 2.1.x you can avoid going through RemoteActorRefProvider by using system.provider.getDefaultAddress)

In Akka if you are using constructing actor addresses this way for use with actorFor then you need to make sure the hostnames match exactly.

For example if the ActorSystem thinks the host is foo.bar.com, then it will ignore the messages sent by a remote host to actorFor("akka://slave@foo:2555/user/slaverunner")



回答2:

For recent akka versions (2.1+) use this:

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

the remotePath is what you were looking for:

I want it to return me the string akka://10.4.20.40:2555/slave/user/slaverunner

For more recent akka versions (2.5.3) use this:

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


回答3:

I got this wrapped String:

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

Using system.settings:

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

Actor was a "root" actor, in a fabric scheme suggested by Viktor Klang in a mail group discussion concerning "determine if actor is dead". It was created like this:

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

from ActorSystem that was created like this:

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"))

Tested in Scala 2.9.2 REPL with Akka 2.0.3 that I still use.

Unwrap actual value using Config docs here: http://typesafehub.github.com/config/v0.3.0/



回答4:

See public address of an actorsystem. Read the full discussion, and note that "normally" you don't need to grab the host/port.



标签: scala akka