如何远程观看Akka Actor?
How to watch remote Akka Actor?
我正在学习 akka-remote,我在 LocalActorSystem
中做的一件事是获取远程 actor 参考并向他发送消息
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
?
- 如何观看 RemoteActor?
更新
然而,弃用的 API 并没有抱怨
val remote = context.actorFor("akka.tcp://HelloRemoteSystem@127.0.0.1:5150/user/RemoteActor")
context watch remote
当您通过 actorSelection
进行查找时,您返回的 object 类型是 ActorSelection
而不是 ActorRef
。现在,ActorSelection
确实支持 tell (!)
和 ask (?)
,因此您可以像 ActorRef
一样与它交互。但是通过 actorSelection
查找演员支持通配符的概念,因此您返回的 ActorSelection
可能代表多个演员,并且允许您向多个演员发送消息。例如,如果您这样做了:
system.actorSelection("/user/foo/*")
这将为您在 parent ActorRef
下的所有 children 提供一个 ActorSelection
绑定到名称 foo
。如果有两个 children 并且您通过那个 ActorSelection
发送消息,则该消息将被传递给两个 children。
在您的例子中,您似乎正在查找单个 actor 实例。在这种情况下,您可以通过调用 resolveOne
从 ActorSelection
中获取 ActorRef
。这将 return 一个 Future[ActorRef]
,完成后将为您提供一个 ActorRef
,您可以远程观看。您还可以向 ActorSelection
发送 Identify
消息并等待 ActorIdentity
包含要观看的 ref 的响应。
您应该查看文档 here,特别是 Identifying Actors via Actor Selection
部分。
我正在学习 akka-remote,我在 LocalActorSystem
中做的一件事是获取远程 actor 参考并向他发送消息
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
? - 如何观看 RemoteActor?
更新
然而,弃用的 API 并没有抱怨
val remote = context.actorFor("akka.tcp://HelloRemoteSystem@127.0.0.1:5150/user/RemoteActor")
context watch remote
当您通过 actorSelection
进行查找时,您返回的 object 类型是 ActorSelection
而不是 ActorRef
。现在,ActorSelection
确实支持 tell (!)
和 ask (?)
,因此您可以像 ActorRef
一样与它交互。但是通过 actorSelection
查找演员支持通配符的概念,因此您返回的 ActorSelection
可能代表多个演员,并且允许您向多个演员发送消息。例如,如果您这样做了:
system.actorSelection("/user/foo/*")
这将为您在 parent ActorRef
下的所有 children 提供一个 ActorSelection
绑定到名称 foo
。如果有两个 children 并且您通过那个 ActorSelection
发送消息,则该消息将被传递给两个 children。
在您的例子中,您似乎正在查找单个 actor 实例。在这种情况下,您可以通过调用 resolveOne
从 ActorSelection
中获取 ActorRef
。这将 return 一个 Future[ActorRef]
,完成后将为您提供一个 ActorRef
,您可以远程观看。您还可以向 ActorSelection
发送 Identify
消息并等待 ActorIdentity
包含要观看的 ref 的响应。
您应该查看文档 here,特别是 Identifying Actors via Actor Selection
部分。