Отправка актера Akka в JSON - PullRequest
4 голосов
/ 23 ноября 2010

Хорошо, поэтому я пишу неявные преобразования для case-классов в scala, используя SJSON, для отправки сообщений удаленным субъектам, используя инфраструктуру akka.Один из классов case выглядит следующим образом:

case class Example(id: String, actr: ActorRef) 

Как мне написать неявное для этого класса case.

Я видел, что в ActorRefs есть метод toBinary, но мне нужноотправь его на Json

1 Ответ

3 голосов
/ 23 ноября 2010
  • http://doc.akkasource.org/serialization-scala. Явная [глубокая] сериализация может потребоваться только для действующих лиц с состоянием, когда базовый экземпляр субъекта (в ActorRef / RemoteActorRef) содержит некоторые важные данные времени выполнения. Для этого случая вы должны реализовать следующий класс типов для вашего актера:
/**
 * Type class definition for Actor Serialization
 */
trait FromBinary[T <: Actor] {
  def fromBinary(bytes: Array[Byte], act: T): T
}

trait ToBinary[T <: Actor] {
  def toBinary(t: T): Array[Byte]
}

// client needs to implement Format[] for the respective actor
trait Format[T <: Actor] extends FromBinary[T] with ToBinary[T]

Если вы хотите сериализацию ScalaJSON вместо стандартной, вы должны использовать SerializerBasedActorFormat trait

trait SerializerBasedActorFormat[T <: Actor] extends Format[T] {
  val serializer: Serializer
  def fromBinary(bytes: Array[Byte], act: T) = serializer.fromBinary(bytes, Some(act.self.actorClass)).asInstanceOf[T]
  def toBinary(ac: T) = serializer.toBinary(ac)
}

с ScalaJSON serializer. Библиотека SJSON поддерживает сериализацию простых объектов Scala без дополнительных настроек (в большинстве случаев этого достаточно). Если вам необходимо игнорировать некоторые свойства или определить политику сериализации встроенных объектов, прочитайте this .

В вашем случае вам понадобится что-то вроде

@BeanInfo
case class Example(id: String, 
@(JSONTypeHint @field)(value = classOf[MyActor])
actr: ActorRef) 

implicit object MyActorFormat extends SerializerBasedActorFormat[MyActor] {
    val serializer = Serializer.ScalaJSON
}
  • Как правило, вам не нужно явно сериализовывать ваши классы дел, когда вы отправляете сообщения удаленным субъектам в Akka - сама Akka сериализует все данные с помощью protobufs перед отправкой по TCP.
  • Зачем вам нужно сериализовать ссылку на актера? Если просто необходимо позвонить отправителю субъекту, который получает сообщение, вы можете просто использовать self.sender, если сообщение было отправлено с ! или self.senderFuture, когда сообщение отправлено с !! или !!!. ActorRef (или RemoteActorRef) сам по себе является просто абстрактным интерфейсом для актера, который используется для инкапсуляции внутренней реализации актера и позволяет внешним связям взаимодействовать с актером только через сообщения (в отличие от акторов stdlib / во многом аналогично тому, как это делается в Erlang [процессов]) и содержит очень небольшое количество данных, которые имеет смысл сериализовать и отправлять по проводам.
...