将 Akka actorRef 发送到 json

发布于 2024-10-04 04:16:06 字数 232 浏览 1 评论 0原文

好的,我正在使用 SJSON 为 scala 中的案例类编写隐式转换,以使用 akka 框架向远程参与者发送消息。其中一个案例类看起来像这样

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

我将如何为该案例类编写隐式内容。

我已经看到 ActorRefs 确实有一个 toBinary 方法,但我需要将其发送到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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

勿挽旧人 2024-10-11 04:16:06
  • http://doc.akkasource.org/serialization-scala 。当底层 Actor 实例(在 ActorRef / RemoteActorRef 下)保存一些重要的运行时数据时,可能仅对有状态 Actor 需要显式[深度]序列化。对于这种情况,您应该为您的参与者实现以下类型类:

<前><代码>/**
* Actor序列化的类型类定义
*/
特征 FromBinary[T <: 演员] {
def fromBinary(字节: Array[Byte], act: T): T
}

特征 ToBinary[T <: 演员] {
def toBinary(t: T): 数组[字节]
}

// 客户端需要为相应的 actor 实现 Format[]
特征 Format[T <: Actor] 扩展 FromBinary[T] 和 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 序列化器
SJSON 库支持开箱即用的普通 Scala 对象的序列化,无需额外配置(在大多数情况下这就足够了)。如果您需要忽略某些属性,或定义嵌入对象的序列化策略,请阅读 这个

在你的情况下,你需要类似的东西

@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 本身在通过 TCP 发送之前使用 protobufs 序列化所有数据。
  • 为什么需要序列化对演员的引用?如果只需要接收消息的参与者调用发送者,则可以简单地使用 self.sender(如果消息是通过 !发送的) self.senderFuture,当消息使用 !!!!! 发送时。 ActorRef(或 RemoteActorRef)本身只是一个 Actor 的抽象接口,用于封装内部 Actor 的实现并让外部仅通过消息与 Actor 进行通信(与 stdlib Actors 相比/很像在 Erlang [进程] 中所做的那样)和保存非常少量的数据,这对于序列化和通过网络发送是有意义的。
  • 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 !, or self.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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文