Java RMI,使对象可序列化和远程
您可能会想为什么要拥有一个既远程又可序列化的对象。好吧,让我给你一些背景信息。
我正在构建一个空中交通管制系统(学校项目),它是分布式的,以便每个控制区域在自己的服务器上运行并与其他控制区域进行通信。每个控制区都跟踪自己的飞机。
当一架飞机(在控制区 A 飞行)距离其边界 100 公里时,它会作为远程物体飞过其附近的控制区(控制区 B)。这样,当飞机仍受控制区 A 控制时,控制区 B 可以看到飞机所在的位置(通过定期询问其位置)。
但是,当飞机越过控制区 A 和 B 之间的边界时,控制区 B 应该跟踪飞机,而不是控制区 A所以我们想要序列化飞机并将其传递给controlZone B。这就是我们的问题所在。
我可以使飞机远程且可序列化吗?
编辑:另外,我可以使用远程方法来复制飞机所需的字段,但我更喜欢将其序列化。
You might be thinking why would you want to have an object both Remote AND serializeable. 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. This way controlzone B can see where the aiplane is (by periodical asking its position) while it's still controlled by controlzone 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.
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果远程对象在作为远程方法参数或结果发送时未导出,则它会被序列化,而不是作为远程引用传递,前提是它实现了 Serialized 和 Remote。然后将其导出到接收器。例如,UnicastRemoteObject 就是这样做的,因此从它派生的任何远程对象也是如此。这可用于移动远程代理。
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. It is then exported at the receiver. UnicastRemoteObject does this for example, and therefore so does any remote object derived from it. This can be used for mobile remote agents.
您不必将对象设为 UnicastRemoteObject 的子类。
获取您的类,定义它来实现 Serialized 和 RMI api 接口,该接口本身应该实现 Remote。除了 java.lang.Object 之外,它不需要子类化任何东西。
当您准备好远程调用对象时,请对其调用静态 UnicastRemoteObject.exportObject() 方法。从那时起,您通过 RMI 返回到该对象的任何引用都将是可远程调用的。
当您想要将对象传递到另一台服务器时,请在您的对象上调用 UnicastRemoteObject.unexportObject() 。然后,当您通过 RMI 调用传递它时,您将传递该对象的序列化表示。
这样做的缺点是一旦您将其传递出去,服务器上的对象将不再接受 RMI 调用。 unexportObject() 将其作为 RMI 调用接收者完全关闭。
如果您希望能够将一个对象维护为 RMI 目标,并同时将其作为可序列化对象通过 RMI 传递,则需要使其可序列化并插入一个代理对象,该代理对象导出 Remote 接口并可以与代表调用者的非导出、可序列化对象。
当你想通过序列化传递底层对象时,你可以直接传递它。当您想向其传递可远程调用的引用时,您可以传递代理。
You don't have to make your object subclass UnicastRemoteObject.
Take your class, define it to implement Serializable and your RMI api interface, which itself should implement Remote. It doesn't need to subclass anything other than java.lang.Object.
When you are ready for your object to be called remotely, call the static UnicastRemoteObject.exportObject() method on it. From that point on, any reference you return over RMI to that object will be remotely callable.
When you want to pass the object off to another server, call UnicastRemoteObject.unexportObject() on your object. Then when you pass it over an RMI call, you'll be passing the serialized representation of that object.
The downside to this is once you pass it off, the object on your server will no longer accept RMI calls. unexportObject() turns it off completely as an RMI call recipient.
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.
When you want to pass the underlying object with serialization, you pass it directly. When you want to pass a remotely callable reference to it, you pass the proxy.
看一下
UnicastRemoteObject
类。它通常用于 RMI 中的回调驱动编程,因此实现了远程和序列化。尽管您可能想重新审视您的逻辑,因为您现在有一个充当“远程服务器”的实体(飞机)。Take a look at
UnicastRemoteObject
class. It is normally used for callback driven programming in RMI and hence implements bothRemote
andSerializable
. Though you might want to revisit your logic since you now have an entity (airplane) which acts like a "remote server".事实证明这个解决方案是不正确的。请参阅下面 @EJP 的答案,了解使用单个实例执行此操作的唯一方法。
Turns out this solution was not correct. See @EJP's answer below for the only way to do this with a single instance.