1

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

case myClass: MyClass => doSomething()

但我得到一个错误local class incompatible,因为serialVersionUID它们不同。

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

那么有没有办法向远程参与者发送强类型消息?如果没有,解决方法是什么?

4

2 回答 2

6

你当然可以!

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

在 Akka 中,用于从一个 Actor 系统传输到另一个 Actor 系统的消息的序列化机制是高度可配置的:您不应该在自己的 Actor 中执行此操作,而是将其留给 Akka 的序列化基础设施(并根据您的喜好进行配置)。

默认情况下,akka 使用内置的“Java 序列化”。这主要是可行的,但正如您所注意到的,在连接的两侧拥有完全相同的类是非常挑剔的。此外,它不是特别快。您应该在日志记录中看到警告:

不推荐使用类 [{}] 的默认 Java 序列化程序,因为这会影响性能。使用另一个序列化程序或使用设置 akka.actor.warn-about-java-serializer-usage 禁用此警告

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

  • 继续使用 Java 序列化,并至少serialVersionUID按照 Vitaliy 的回答中的描述进行固定。
  • 切换到另一种序列化机制,例如 Protobuf。

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

关于如何配置 akka 的序列化机制的更多文档可以在http://doc.akka.io/docs/akka/current/scala/serialization.html#serialization-scala找到

于 2016-05-14T15:46:49.520 回答
1

Serializable javadoc

强烈建议所有可序列化类显式声明 serialVersionUID 值,因为默认的 serialVersionUID 计算对类细节高度敏感,这些细节可能因编译器实现而异,因此可能在反序列化期间导致意外的 InvalidClassExceptions。

因此,您应该serialVersionUID在消息类中定义如下:

@SerialVersionUID(42L)
class Message extends Serializable
于 2016-05-14T15:30:16.713 回答