2010-11-23 6 views
3

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

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

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

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

ответ

3
  • 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 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 
} 
  • В общем, вам не нужно сериализовать классы регистра явным образом, при отправке сообщений на удаленные акторы в Акку - Акку сама сериализует все данные с protobufs перед отправкой через TCP.
  • Зачем вам нужно сериализовать ссылку на актера? Если вам просто нужно позвонить отправителю актером, который получает сообщение, вы можете просто использовать self.sender, если сообщение было отправлено с ! или self.senderFuture, когда сообщения отправляются с !! или !!!. ActorRef (или RemoteActorRef) сам по себе является абстрактным интерфейсом к актеру, используемому для инкапсуляции внутренней актерской реализации и позволяя внешнему сообществу общаться с актером только через сообщения (в отличие от stdlib Актеры/как это сделано в Erlang [процессы]) и содержит очень малое количество данных, которое имеет смысл сериализовать и передавать по проводам.
+0

Удивительное спасибо за помощь. Вы случайно знаете, если это будет работать для класса case, который наследуется от запечатанной черты. – trjohn06 2010-11-23 19:59:33