Actor 消息应该在哪里声明?

Where should actor messages be declared?

我正在使用 Akka 开发一个应用程序,而关于使用 Actor 进行消息声明这件事一直困扰着我。我应该在哪里声明消息?在接收者伙伴对象或发送者伙伴对象中或在某个第三方位置?

Akka 团队建议 Message 应该定义在与 props 方法相同的地方:in the Receiver's Companion object 因为 Receiver 实现了 receive 部分函数并且需要知道所有它支持的消息。此外,多个发送者可以发送一组消息(由接收者实现),因此您不能将其放在一个发送者中。

如果 the official Typesafe Activator template activator-akka-scala-seed 对于 Akka 的良好实践有任何重要性,则消息应该是伴随对象的一部分,如下面的 PingActor 参与者(直接从模板复制)所示:

package com.example

import akka.actor.{Actor, ActorLogging, Props}

class PingActor extends Actor with ActorLogging {
  import PingActor._

  var counter = 0
  val pongActor = context.actorOf(PongActor.props, "pongActor")

  def receive = {
    case Initialize => 
      log.info("In PingActor - starting ping-pong")
      pongActor ! PingMessage("ping")   
    case PongActor.PongMessage(text) =>
      log.info("In PingActor - received message: {}", text)
      counter += 1
      if (counter == 3) context.system.shutdown()
      else sender() ! PingMessage("ping")
  } 
}

object PingActor {
  val props = Props[PingActor]
  case object Initialize
  case class PingMessage(text: String)
}

注意 PingActor 保存了演员接受的所有消息(你可能已经注意到它没有被严格遵守,因为 PongActor.PongMessage 也被接受,但没有在伴随对象中定义 PingActor).

来自另一个问题How to restrict actor messages to specific types? the Viktor said:

The common practice is to declare what messages an Actor can receive in the companion object of the Actor, which makes it very much easier to know what it can receive.