您可以准确地解决您的问题,其中Stash
特征和become/unbecome
功能的Akka。这个想法如下:
当您收到一个Stop
消息,然后你切换到一种行为,你藏匿所有不是Start
的邮件。当您收到Start
消息,然后切换到您打印所有收到的消息,另外你unstash其在此期间已经到达所有消息的行为。
case object Start
case object Stop
case object TriggerStateChange
case object SendMessage
class ActorB extends Actor with Stash {
override def receive: Receive = {
case Start =>
context.become(printingBehavior, false)
unstashAll()
case x => stash()
}
def printingBehavior: Receive = {
case msg: String => println(msg)
case Stop => context.unbecome()
}
}
class ActorA(val actorB: ActorRef) extends Actor {
var counter = 0
var started = false
override def preStart: Unit = {
import context.dispatcher
this.context.system.scheduler.schedule(0 seconds, 5 seconds, self, TriggerStateChange)
this.context.system.scheduler.schedule(0 seconds, 1 seconds, self, SendMessage)
}
override def receive: Actor.Receive = {
case SendMessage =>
actorB ! "Message: " + counter
counter += 1
case TriggerStateChange =>
actorB ! (if (started) {
started = false
Stop
} else {
started = true
Start
})
}
}
object Akka {
def main(args: Array[String]) = {
val system = ActorSystem.create("TestActorSystem")
val actorB = system.actorOf(Props(classOf[ActorB]), "ActorB")
val actorA = system.actorOf(Props(classOf[ActorA], actorB), "ActorA")
system.awaitTermination()
}
}
'unstashAll()'是否保留了消息的顺序?我的意思是,如果我有 “开始-M1-M2-停止-M3-M4-M5-开始-M6-M7停止”,将打印顺序是 “M1-M2-M3-M4-M5-M6-M7”或者可以在M3,M4和M5之前读取M6(如果在'unstashAll()'之后接收到M6)? –
@AsAs,内部的'unstashAll()'方法调用邮箱上的enqueueFirst。因此,我假设你将首先按照它们被隐藏的顺序接收你的未压缩的消息,然后接收在'unstashAll()'调用期间或之后收到的任何消息。 –
谢谢。另一件事。我可以给予更高的优先级来启动/停止消息吗?如果ActorB收到“Start-M1-M2-M3”,然后在打印“M1”时收到停止消息,我希望ActorB再次保存M2和M3。可能吗? –