有没有办法将用我自己的类输入的消息发送给Akka远程演员?

时间:2016-05-14 12:48:25

标签: scala akka akka-remote-actor

有没有办法将使用我自己的类输入的消息发送给远程actor? 例如,我希望能够在我的远程演员中收到这样的消息:

case myClass: MyClass => doSomething()

但我收到错误local class incompatible,因为serialVersionUID不同。

发送MyClass类型的消息的唯一方法是在Json中序列化它。但是我必须序列化/反序列化它,并且更有问题,我没有一种干净的方式来接收两种类型的消息...

那么有没有办法将强类型消息发送给远程actor?如果没有,解决方法是什么?

2 个答案:

答案 0 :(得分:6)

你当然可以!

通过网络发送对象时,必须将它们转换为一端的字节,然后转换回另一端的对象。这称为“序列化”。

在Akka中,用于从一个actor系统传播到另一个actor系统的消息的序列化机制是高度可配置的:你不应该在自己的actor中执行它,而是将它留给Akka的序列化基础结构(并根据自己的喜好进行配置)。

默认情况下,akka使用内置的“Java序列化”。这大部分都有效,但正如您所注意到的那样,在连接的两侧都有完全相同的类是非常挑剔的。而且,它并不是特别快。您应该在日志记录中看到警告:

  

使用类[{}}的默认Java序列化程序,而不是   建议,因为性能影响。使用另一个   序列化程序或使用该设置禁用此警告   akka.actor.warn-约-java的串行器 - 使用

要解决您的问题,您可以:

  • 继续使用Java序列化,至少按照Vitaliy的回答中的说明修改serialVersionUID
  • 切换到另一个序列化机制,例如Protobuf。

如果您不太关心性能并且不期望进行“滚动升级”(您可能需要在同一消息的不同版本之间进行转换),那么Java序列化肯定是最简单的。但是,重要的是要意识到它的局限性。

有关如何配置akka序列化机制的更多文档,请参阅http://doc.akka.io/docs/akka/current/scala/serialization.html#serialization-scala

答案 1 :(得分:1)

来自Serializable javadoc

  

强烈建议明确显示所有可序列化类   声明serialVersionUID值,因为默认的serialVersionUID   计算对可能不同的类详细信息非常敏感   取决于编译器实现,因此可以导致   反序列化期间出现意外的InvalidClassExceptions。

因此,您应该在邮件类中定义serialVersionUID,如下所示:

@SerialVersionUID(42L)
class Message extends Serializable