Sending an Akka actorRef to json
Ok so i am writing implicit conversions for case classes in scala, using SJSON, to send messages to remote actors 开发者_开发问答using the akka framework. One of the case classes looks like this
case class Example(id: String, actr: ActorRef)
How would i go about writing the implicit for this case class.
I have seen that ActorRefs do have a toBinary method but i need to send it toJson
- http://doc.akkasource.org/serialization-scala . Explicit [deep] serialization may be required only for stateful actors, when underlying actor instance (under ActorRef / RemoteActorRef) holds some important runtime data. For this case, you should implement the following typeclass for your actor:
/** * 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]
If you want ScalaJSON serialization, instead of the default one, you should use 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)
}
with ScalaJSON serializer
.
SJSON library supports serialization of plain Scala objects out-of-box, without an additional configuration (which is enough, in the most cases). If you need to ignore some properties, or define serialization policy of embedded objects, read this.
In your case, you would need something like
@BeanInfo
case class Example(id: String,
@(JSONTypeHint @field)(value = classOf[MyActor])
actr: ActorRef)
implicit object MyActorFormat extends SerializerBasedActorFormat[MyActor] {
val serializer = Serializer.ScalaJSON
}
- In general, you don't need to serialize your case classes explicitly, when you're sending messages to remote actors in Akka - Akka itself serializes all data with protobufs before sending over TCP.
- Why would you need serialize reference to the actor? If it's just needed to call the sender by the actor that receives the message, you can simply use
self.sender
, if the message was sent with!
, orself.senderFuture
, when the messages is sent with!!
or!!!
. ActorRef (or RemoteActorRef) on itself is just an abstract interface to an actor, used to encapsulate internal actor's implementation and letting externals communicate with the actor only via messages (in contrast to stdlib Actors / much like it's done in Erlang [processes]) and holds very small amount of data that makes sense to serialize and send over wire.
精彩评论