Envoi d'un actorRef à Akka JSON
Question
Ok donc je suis en train d'écrire 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 se présente comme suit
case class Example(id: String, actr: ActorRef)
Comment puis-je aller sur l'écriture de l'implicite pour cette classe de cas.
Je l'ai vu que ActorRefs ont une méthode toBinary mais je dois l'envoyer toJson
La solution
- http://doc.akkasource.org/serialization-scala . Explicite [profond] sérialisation peut être exigée que pour les acteurs, quand stateful sous-jacente par exemple de l'acteur (sous ActorRef / RemoteActorRef) détient des données d'exécution importantes. Dans ce cas, vous devez mettre en œuvre le suivant pour votre classe de types 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 celui par défaut, vous devez utiliser trait 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)
}
avec ScalaJSON serializer
.
SJSON supports bibliothèque sérialisation d'objets Scala plaine hors-boîte, sans configuration supplémentaire (ce qui est suffisant dans la plupart des cas). Si vous avez besoin d'ignorer certaines propriétés ou définir la politique de sérialisation d'objets incorporés, lisez ce .
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 se sérialise toutes les données avec protobufs avant de l'envoyer sur TCP.
- Pourquoi auriez-vous besoin sérialisation référence à l'acteur? S'il est juste nécessaire 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!
ouself.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 détient très petite quantité de données qui fait sens pour sérialiser et envoyer sur le fil.