【问题标题】:How can objects be updated rather than completely written anew when sending through ObjectInputStream通过 ObjectInputStream 发送时如何更新对象而不是完全重新编写对象
【发布时间】:2017-12-20 01:28:23
【问题描述】:

以下实现了通过 ObjectOutputStream 发送的更新对象(在这种情况下使用套接字),但它必须每次都完全重写对象以更新另一端的对象,因为否则对象使用引用旧的反向引用对象已发送并且不查看新对象。我不知道如果这样的东西每秒更新几次会不会出现性能问题,但是有什么方法可以更有效地做到这一点?

ObjectOutputStream objectOS = new ObjectOutputStream(connectionSocket.getOutputStream());
while(true){

        objectOS.reset(); // Disgregard any objects already written to stream

        System.out.println(kingBob.currentAge);
        objectOS.writeObject(kingBob);

        System.out.println("Update HP");
        kingBob.updateCurrentAge(keyboard.nextInt());

}

【问题讨论】:

  • 无需为了检查状态变化而每秒多次重新发送整个对象。特别是对于高吞吐量的游戏网络,你真的应该只发送一个轻量级的信号来通知对方需要更新状态。
  • @Vince Emigh,不是发送整个对象,而是发送需要更新的字段?
  • 发送一个操作码(通常是一个数字),通知对方需要做什么。每一方都会监听符合协议的操作码。如果客户端想要告诉服务器更新年龄,它会发送“更新年龄”操作码(例如,0)。服务器将收到操作码。根据操作码,服务器将自行设置为读取更多数据(例如年龄本身)。不要为此使用对象流。
  • @VinceEmigh 谢谢!

标签: java sockets serialization objectoutputstream backreference


【解决方案1】:

Java 并没有真正具有一般复制或更新对象甚至检测差异的内置概念,您可以获得的最接近的是将对象序列化为数组并返回复制它,这明显很慢而且仍然需要一些支持。

关键是你必须自己做,但你可以编写代码以更通用地工作。

Java 中只有少数“事物”。有扩展“对象”的内在类型和类。如果将两个“对象”传递给一个方法,则该方法可以迭代相同类型的两个对象,反射性地配对字段,识别每个字段的类型——如果字段是固有的,则复制值,如果field 是一个子类,向下递归该类以复制 IT 的成员。这将使您的原始参考文献保持原样。

这有点痛苦但可行——也许现在有人已经在那里写了一个库,我不得不手工完成..

如果它适合您的问题空间,那么更好的选择可能是查看 RMI 解决方案。如果您的对象是“远程”,那么调用者可以直接调用您的设置器之一。

注意:我的问题与您的问题不完全一样,但很接近,我必须检测两个数据库之间的更改对象,复制一些更改并记录它们。我最终注释了我想要复制的字段。当您必须使用反射时,注释非常有用。

【讨论】:

  • 欣赏答案! & 我会看看 RMI
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-25
  • 1970-01-01
  • 2013-07-13
  • 1970-01-01
  • 2012-04-24
  • 2018-04-12
相关资源
最近更新 更多