I am learning akka-remote and one of the things I do in my LocalActorSystem
is getting remote actor reference and send messages to him
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
}
}
}
My Remote
looks like
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"
}
}
I also wanted to watch remoteActor
so that if its dead, LocalActorSystem get to know. So I did
val remote = context.actorSelection("akka.tcp://[email protected]:5150/user/RemoteActor")
context watch remote
but then compiler fails with following message
Question
- How come I am able to send message to
ActorSelection
since it is notActor
? - How can I watch RemoteActor?
Update
However, the deprecated API does not complain
val remote = context.actorFor("akka.tcp://[email protected]:5150/user/RemoteActor")
context watch remote
When you do a lookup via
actorSelection
, that type of object you get back is anActorSelection
and not anActorRef
. Now, anActorSelection
does support bothtell (!)
andask (?)
so you can interact with it the same way you would anActorRef
. But an looking up actors viaactorSelection
supports the concept of a wild card, so theActorSelection
you get back potentially represents more than one actor and would allow you to send messages to more than one actor. For instance, if you did :system.actorSelection("/user/foo/*")
this would give you an
ActorSelection
for all children under the parentActorRef
bound to the namefoo
. If there were two children and you send a message via thatActorSelection
, that message would be delivered to both children.In your case, it looks like you are looking up a single actor instance. In that case, you can get an
ActorRef
from yourActorSelection
by callingresolveOne
on it. This will return aFuture[ActorRef]
that when completed will provide you with anActorRef
that you can watch remotely. You could also send theActorSelection
anIdentify
message and wait for theActorIdentity
response containing the ref to watch.You should check out the docs here, specifically the
Identifying Actors via Actor Selection
section.