简体   繁体   English

Java RMI,使 object 可序列化和远程

[英]Java RMI, making an object serializeable AND remote

You might be thinking why would you want to have an object both Remote AND serializeable.您可能会想,为什么要拥有一个远程和可序列化的 object。 Well let me give you some context.好吧,让我给你一些背景。

I'm building an air traffic control system (school project), it's distributed so that each control zone runs on it's own server and communicates with other control zones.我正在构建一个空中交通管制系统(学校项目),它是分布式的,以便每个控制区在它自己的服务器上运行并与其他控制区通信。 Each control zone keeps track of its own aiplanes.每个控制区都跟踪自己的飞机。

When an airplane (flying in controlzone A) is 100km near its border, it is passed as a remote object to the controlzone (controlzone B) it's near to.当一架飞机(在控制区 A 飞行)在其边界附近 100 公里处时,它将作为远程 object 传递到它附近的控制区(控制区 B)。 This way controlzone B can see where the aiplane is (by periodical asking its position) while it's still controlled by controlzone A.这样控制区 B 可以看到飞机在哪里(通过定期询问它的位置),而它仍然由控制区 A 控制。

But when an airplane crosses the border between controlzone A and B, controlzone B should keep track of the airplane instead of controlzone A. So we we want to serialize the airplane and pass it to controlZone B. This is where our problem lies.但是当飞机越过控制区 A 和 B 之间的边界时,控制区 B 应该跟踪飞机而不是控制区 A。所以我们要序列化飞机并将其传递给 controlZone B。这就是我们的问题所在。

Can I make the airplane remote AND serializeable?我可以使飞机远程和可序列化吗?

EDIT: Also, I could use remote methods to copy the needed fields for the airplane, but I prefer serializing it.编辑:另外,我可以使用远程方法来复制飞机所需的字段,但我更喜欢序列化它。

If a remote object isn't exported at the time it is sent as a remote method parameter or result, it is serialized instead of being passed as a remote reference, provided that it implements Serializable as well as Remote.如果远程 object 在作为远程方法参数或结果发送时未导出,则将对其进行序列化而不是作为远程引用传递,前提是它实现了可序列化和远程。 It is then exported at the receiver.然后在接收器处导出。 UnicastRemoteObject does this for example, and therefore so does any remote object derived from it.例如,UnicastRemoteObject 执行此操作,因此从它派生的任何远程 object 也是如此。 This can be used for mobile remote agents.这可用于移动远程代理。

You don't have to make your object subclass UnicastRemoteObject.您不必使您的 object 成为 UnicastRemoteObject 的子类。

Take your class, define it to implement Serializable and your RMI api interface, which itself should implement Remote.拿你的 class,定义它来实现 Serializable 和你的 RMI api 接口,它本身应该实现远程。 It doesn't need to subclass anything other than java.lang.Object.它不需要继承 java.lang.Object 以外的任何东西。

When you are ready for your object to be called remotely, call the static UnicastRemoteObject.exportObject() method on it.当您准备好远程调用 object 时,请在其上调用 static UnicastRemoteObject.exportObject() 方法。 From that point on, any reference you return over RMI to that object will be remotely callable.从那时起,您通过 RMI 返回到 object 的任何引用都将是可远程调用的。

When you want to pass the object off to another server, call UnicastRemoteObject.unexportObject() on your object.当您想将 object 传递给另一台服务器时,请在 object 上调用 UnicastRemoteObject.unexportObject()。 Then when you pass it over an RMI call, you'll be passing the serialized representation of that object.然后,当您通过 RMI 调用传递它时,您将传递该 object 的序列化表示。

The downside to this is once you pass it off, the object on your server will no longer accept RMI calls.这样做的缺点是,一旦您将其传递出去,您服务器上的 object 将不再接受 RMI 调用。 unexportObject() turns it off completely as an RMI call recipient. unexportObject() 作为 RMI 调用接收者将其完全关闭。

If you want to be able to maintain an object as an RMI target and concurrently pass it around over RMI as a serializable object, you'll need to make it serializable and interpose a proxy object that exports the Remote interface and which can talk to the non-exported, serializable object on the caller's behalf.如果您希望能够将 object 维护为 RMI 目标,并同时将其作为可序列化 object 通过 RMI 传递,则需要使其可序列化并插入代理 ZA8CFDE6331BD59EB2AC96F8911C4B6代表调用者的非导出的、可序列化的 object。

When you want to pass the underlying object with serialization, you pass it directly.当你想通过序列化传递底层 object 时,你直接传递它。 When you want to pass a remotely callable reference to it, you pass the proxy.当你想传递一个远程可调用的引用时,你传递代理。

Take a look at UnicastRemoteObject class.看看UnicastRemoteObject class。 It is normally used for callback driven programming in RMI and hence implements both Remote and Serializable .它通常用于 RMI 中的回调驱动编程,因此实现RemoteSerializable Though you might want to revisit your logic since you now have an entity (airplane) which acts like a "remote server".尽管您可能想要重新审视您的逻辑,因为您现在拥有一个充当“远程服务器”的实体(飞机)。

Turns out this solution was not correct.原来这个解决方案是不正确的。 See @EJP's answer below for the only way to do this with a single instance.有关使用单个实例执行此操作的唯一方法,请参见下面的@EJP 答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM