您可以準確地解決您的問題,其中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。可能嗎? –