有没有办法将用自己的类键入的消息发送给远程参与者
例如,我希望能够在我的远程演员中收到这样的消息:
case myClass: MyClass => doSomething()
但是我得到了一个错误local class incompatible
,因为serialVersionUID
是不同的。
发送我找到的MyClass类型的消息的唯一方法是在Json中序列化它。但我必须对它进行序列化/反序列化,更麻烦的是,我没有一种干净的方法来接收两种类型的消息。。。
那么,有没有一种方法可以向远程参与者发送强类型消息呢?如果没有,解决方法是什么?
你当然可以!
在网络上发送对象时,必须在一端将其转换为字节,在另一端将其重新转换为对象。这称为"序列化"。
在Akka中,用于消息从一个参与者系统传输到另一个参与者的序列化机制是高度可配置的:您不应该在自己的参与者中这样做,而是由Akka的序列化基础设施来决定(并根据您的喜好进行配置)。
默认情况下,akka使用内置的"Java序列化"。这基本上是有效的,但正如您所注意到的,在连接的两侧都有完全相同的类是非常挑剔的。此外,它也不是特别快。你应该在日志中看到一个警告:
使用类〔{}〕的默认Java序列化程序由于性能影响,建议使用。使用其他序列化程序或使用设置禁用此警告akka.actor.warn-about-java-serializer-usage
要解决您的问题,您可以:
- 继续使用Java序列化,至少修复Vitaliy的回答中描述的
serialVersionUID
- 切换到另一种序列化机制,如Protobuf
如果您不太关心性能,也不希望进行"滚动升级"(可能需要在同一消息的不同版本之间进行转换),那么Java序列化无疑是最简单的。不过,重要的是要意识到它的局限性。
有关如何配置akka序列化机制的更多文档,请访问http://doc.akka.io/docs/akka/current/scala/serialization.html#serialization-scala
来自Serializable
javadoc:
强烈建议所有可序列化类都显式声明serialVersionUID值,因为默认的serialVersionGUID计算对可能变化的类细节高度敏感取决于编译器实现,因此可能导致反序列化过程中出现意外的InvalidClassException。
因此,您应该在消息类中定义serialVersionUID
,如下所示:
@SerialVersionUID(42L)
class Message extends Serializable