我定义了以下消息和参与者:
case class Message1(text: String)
case class Message2(text: String)
case class Message3(text: String)
class Actor1(actor2: ActorRef) extends Actor {
def receive = {
case Message1(text) =>
(actor2 ? Message2(text)).mapTo[Message3].foreach(self ! _)
case Message3(text) =>
println(s"Got the message[$sender]: " + text)
}
}
class Actor2 extends Actor {
def receive = {
case Message2(text) =>
println(s"Actor2[$self] received: " + text)
sender ! Message3("Received message1: " + text)
}
}
def main(args: Array[String]): Unit = {
val system = ActorSystem("Test")
system.actorOf(Props(new Actor1(system.actorOf(Props(new Actor2))))) ! Message1("Hello")
}
当我运行此代码时,Actor1收到Message3时的输出暗示它仅接收从Future.foreach内部发送的Message3,而不是Actor2发送回的消息3-因为这是由Ask模式处理的。
所以我的问题是:这始终是预期的行为吗?
答案 0 :(得分:3)
是的,这实际上是预期的行为。
ask的主要目的是创建一个虚拟ActorRef,该虚拟ActorRef的使用资源不如一个全副武装的actor充当您可以回复的发件人。
它只包装一个诺言,当收到消息并从Ask函数返回前途时,诺言就会完成。
因此,尽管从技术上讲您是从Actor1询问的,但Actor2中的sender()将是询问创建的伪PromiseActor,这就是为什么您不从Actor2接收Message2的原因。
答案 1 :(得分:2)
ask
(?
)创建一个内部参与者来处理回复。通常,使用tell
(!
)代替ask
进行角色间通信:
class Actor1(actor2: ActorRef) extends Actor {
def receive = {
case Message1(text) =>
actor2 ! Message2(text)
case Message3(text) =>
println(s"Got the message[$sender]: $text")
}
}