2013-01-11 77 views
8

我想要做這樣的事情。如何從演員內部獲取絕對的遠程演員網址?

演員答:

actorB ! "info" 

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

     } 
} 

演員B:(這個遠程部署)

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

    } 

} 

我希望它返回我的字符串阿卡://10.4.20.40:2555 /從/用戶/ slaverunner。但我得到的只是akka://奴隸。我如何獲得遠程主機和端口? 。性能主機,端口和HOSTPORT地址對象不返回任何

回答

7

如果你打電話

sender.path.toString 

的男演員,你會得到發送者的地址。因此,只要您可以向其發送消息,您就不需要將地址傳遞給其他演員系統。

Akka不會給你一個在本地系統中的演員的遠程路徑,這就是爲什麼self.path.address.toString在演員B中將無法工作。

如果您確實想將主機和端口從B發送到A,那麼您需要通過ExtendedActorSystem訪問RemoteActorRefProvider。官方的方式是通過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

遠程通信

(注意,此代碼與阿卡2.0.x的在2.1.x的,你可以儘量避免前往的確切地址通過RemoteActorRefProvider使用system.provider.getDefaultAddress

在阿卡,如果你正在使用構建演員地址這種方式與actorFor使用,那麼你需要確保主機名完全匹配。

例如,如果ActorSystem認爲宿主是foo.bar.com,那麼它將忽略由遠程主機發送的消息到actorFor("akka://[email protected]:2555/user/slaverunner")

+0

你應該最肯定不行:「context.system.asInstanceOf [ExtendedActorSystem] .provider.asInstanceOf [RemoteActorRefProvider] .transport.address」。任何和所有盲目鑄造完全不受支持。請閱讀文檔以瞭解如何完成此任務的說明,我向你保證它在那裏。 –

+0

通過'RemoteActorRefProvider'消除了不受支持的投射,並添加了Akka 2.1的示例。 – sourcedelica

+0

您剛剛爲MatchError交易了一個ClassCastException。代碼會執行細節更改會怎樣? –

1

我得到這個包裹String

ConfigString("akka://[email protected]: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://[email protected]:2552" 
     }  
     } 
    } 
    remote { 
     netty { 
     hostname = "127.0.0.1" 
     port = 2552 
     } 
    } 
    } 
} 
""").getConfig("serverconf")) 

Scala的測試2.9.2 REPL與阿卡2.0.3,我仍然可以使用。

使用Config文檔這裏展開實際值:http://typesafehub.github.com/config/v0.3.0/

+0

獲得全球地址可能帶來的討論到一個新水平的更好的想法=) – idonnie

1

參見public address of an actorsystem。 閱讀完整的討論,並注意「通常」您不需要抓住主機/端口。

+0

Patrik,我試圖建立一個PoC,其中涉及到奴隸主與自己註冊的主人。這是我的用例 – questionersam

1

對於近期阿卡版本(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/slave/user/slaverunner

For more recent阿卡版本(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) 
}