我正在学习akka-remote,我在LocalActorSystem
中做的一件事就是获取远程演员参考并向他发送消息
class LocalActor extends Actor {
val remote = context.actorSelection("akka.tcp://HelloRemoteSystem@127.0.0.1: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://HelloRemoteSystem@127.0.0.1:5150/user/RemoteActor")
context watch remote
但是编译器失败并显示以下消息
问题
ActorSelection
发送消息,因为它不是Actor
? 更新
但是,弃用的API不会抱怨
val remote = context.actorFor("akka.tcp://HelloRemoteSystem@127.0.0.1:5150/user/RemoteActor")
context watch remote
答案 0 :(得分:7)
当您通过actorSelection
进行查询时,您获得的该类型的对象是ActorSelection
,而不是ActorRef
。现在,ActorSelection
同时支持tell (!)
和ask (?)
,因此您可以像ActorRef
一样与其进行互动。但是通过actorSelection
查找的演员支持外卡的概念,因此你回来的ActorSelection
可能代表多个演员,并允许你向多个演员发送消息。例如,如果您这样做:
system.actorSelection("/user/foo/*")
对于名为ActorSelection
的父ActorRef
下的所有子项,这将为您提供foo
。如果有两个孩子并且您通过ActorSelection
发送了一条消息,则该消息将发送给两个孩子。
在您的情况下,看起来您正在查找单个actor实例。在这种情况下,您可以通过调用ActorRef
从ActorSelection
获取resolveOne
。这将返回Future[ActorRef]
,完成后会为您提供可以远程观看的ActorRef
。您还可以发送ActorSelection
Identify
条消息,并等待包含要观看的参考的ActorIdentity
响应。
您应该查看文档here,特别是Identifying Actors via Actor Selection
部分。