我正在学习 akka-remote,我在 LocalActorSystem
中做的一件事是获取远程 Actor 引用并向他发送消息
class LocalActor extends Actor {
val remote = context.actorSelection("akka.tcp://[email protected]:5150/user/RemoteActor")
var counter = 0
def receive = {
case "START" =>
remote ! "Hello from the LocalActor"
case msg: String =>
println(s"LocalActor received message: '$msg'")
if (counter < 5) {
sender ! "Hello back to you"
counter += 1
}
}
}
我的
Remote
看起来像object Remote extends App {
val system = ActorSystem("HelloRemoteSystem", ConfigFactory.load("remote"))
val remoteActor = system.actorOf(Props[RemoteActor], name = "RemoteActor")
remoteActor ! "The RemoteActor is alive"
}
class RemoteActor extends Actor {
def receive = {
case msg: String =>
println(s"RemoteActor received message '$msg'")
sender ! "Hello from the RemoteActor"
}
}
我还想看
remoteActor
,这样如果它死了,LocalActorSystem 就会知道。所以我做了 val remote = context.actorSelection("akka.tcp://[email protected]:5150/user/RemoteActor")
context watch remote
但随后编译器失败并显示以下消息
问题
ActorSelection
发送消息,因为它不是 Actor
? 更新
但是,已弃用的 API 不会提示
val remote = context.actorFor("akka.tcp://[email protected]:5150/user/RemoteActor")
context watch remote
最佳答案
当您通过 actorSelection
进行查找时,您返回的对象类型是 ActorSelection
而不是 ActorRef
。现在,ActorSelection
确实支持 tell (!)
和 ask (?)
,因此您可以像处理 ActorRef
一样与其交互。但是通过 actorSelection
查找 actor 支持通配符的概念,因此您返回的 ActorSelection
可能代表多个 actor,并允许您向多个 actor 发送消息。例如,如果你这样做:system.actorSelection("/user/foo/*")
这将为绑定(bind)到名称 ActorSelection
的父 ActorRef
下的所有 child 提供 foo
。如果有两个 child 并且您通过该 ActorSelection
发送消息,则该消息将传递给两个 child 。
在您的情况下,您似乎正在查找单个 actor 实例。在这种情况下,您可以通过调用 ActorRef
从 ActorSelection
中获取 resolveOne
。这将返回一个 Future[ActorRef]
,完成后将为您提供一个您可以远程观看的 ActorRef
。您还可以向 ActorSelection
发送 Identify
消息并等待包含要观看的 ref 的 ActorIdentity
响应。
您应该查看文档 here ,特别是 Identifying Actors via Actor Selection
部分。