2010-11-23 19 views
3

Ok donc je vous écris des conversions implicites pour les classes de cas scala, en utilisant SJSON, pour envoyer des messages aux acteurs distants à l'aide du cadre de Akka. Une des classes de cas ressemble à ceciEnvoi d'un Akka actorRef à JSON

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

Comment irais-je écrire l'implicite pour cette classe de cas.

Je l'ai vu que ActorRefs ont une méthode toBinary mais je dois l'envoyer toJSON

Répondre

3
  • http://doc.akkasource.org/serialization-scala. La sérialisation explicite [deep] peut être requise uniquement pour les acteurs avec état, lorsque l'instance d'acteur sous-jacente (sous ActorRef/RemoteActorRef) contient des données d'exécution importantes. Dans ce cas, vous devez mettre en œuvre la classe de types suivants pour votre acteur:
/** 
* 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] 

Si vous voulez sérialisation ScalaJSON, au lieu de la valeur par défaut un, vous devez utiliser 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) 
} 

avec ScalaJSON serializer. La bibliothèque SJSON prend en charge la sérialisation des objets Scala simples, sans configuration supplémentaire (ce qui est suffisant dans la plupart des cas). Si vous devez ignorer certaines propriétés ou définir la stratégie de sérialisation des objets incorporés, lisez this.

Dans votre cas, vous auriez besoin de quelque chose comme

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

implicit object MyActorFormat extends SerializerBasedActorFormat[MyActor] { 
    val serializer = Serializer.ScalaJSON 
} 
  • En général, vous n'avez pas besoin de sérialisation vos classes de cas explicitement, lorsque vous envoyez des messages aux acteurs distants dans Akka - Akka lui-même sérialise toutes les données avec protobufs avant d'envoyer TCP.
  • Pourquoi auriez-vous besoin sérialisation référence à l'acteur? S'il suffit d'appeler l'expéditeur par l'acteur qui reçoit le message, vous pouvez simplement utiliser self.sender, si le message a été envoyé avec ! ou self.senderFuture, lorsque les messages sont envoyés avec !! ou !!!. ActorRef (ou RemoteActorRef) sur lui-même est juste une interface abstraite à un acteur, utilisé pour encapsuler la mise en œuvre des acteurs internes et de laisser les externals communiquer avec l'acteur que par des messages (contrairement à stdlib Acteurs/un peu comme cela se fait dans Erlang [processus]) et contient une très petite quantité de données logique pour sérialiser et envoyer par câble.
+0

merci Impressionnant pour l'aide. Savez-vous si cela fonctionnera pour une classe de cas qui hérite d'un trait scellé? – trjohn06

+0

Bien sûr, ça va marcher –