Java RMI:更新服务器中的客户端对象

我正在尝试使用Java RMI在分布式系统中实现用于组通信的中间件。
在那里,我需要将一个对象发送到服务器并进行修改。 所以这些变化应该反映在客户端。

例如,我将在Oracle网站上提供最常见的教程。

X.java

public class X implements Serializable, Remote{ public int x; // defined as public, just be simple. } 

Hello.java

 import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote { String sayHello(X c) throws RemoteException; } 

Server.java

 import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; import java.rmi.server.UnicastRemoteObject; public class Server implements Hello { public Server() { } public String sayHello(X c) { cx = 10; return "Hello, world!"; } public static void main(String args[]) { try { Server obj = new Server(); Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0); LocateRegistry.createRegistry(1099); // Bind the remote object's stub in the registry Registry registry = LocateRegistry.getRegistry(); registry.bind("Hello", stub); System.err.println("Server ready"); } catch (Exception e) { System.err.println("Server exception: " + e.toString()); e.printStackTrace(); } } } 

Client.java

 import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class Client { public int x = 4; private Client() { } public static void main(String[] args) { String host = (args.length < 1) ? null : args[0]; try { Registry registry = LocateRegistry.getRegistry(host); Hello stub = (Hello) registry.lookup("Hello"); X x = new X(); String response = stub.sayHello(x); System.out.println("response: " + xx); } catch (Exception e) { System.err.println("Client exception: " + e.toString()); e.printStackTrace(); } } } 

我的问题是,即使我在服务器端更新对象c中的x的值,它也不会反映到客户端。 我只是可以使用return来获取更新的值,但我打算使用此方法为服务器实现多播function。

有人可以解释为什么吗 如果我需要这样做,那么这样做的方式是什么?

当您使用RMI时,您在给定计算中涉及2个(或更多)Java虚拟机,因此当您在客户端创建对象并在服务器上调用方法时,将此对象作为参数传递,对象的状态将被序列化并通过网络发送。 在服务器端,创建同一类的新对象并在其上设置状态,但它是一个具有相同值的不同对象。 对此克隆进行操作不会反映仍驻留在源虚拟机上的原始对象。

您必须在运行虚拟机的每台计算机上使用rmiregistry并注册每个对象以公开它(这是一个分布式解决方案),或者您可以将所有数据对象集中在具有rmiregistry的计算机上(这是一个集中式解决方案) ,因为所有对象都在同一台机器上)。

干杯

RMI并不神奇。 它是远程方法调用。 您必须调用远程方法才能在远程位置发生某些事情。 只是更改变量并使其在网络中神奇地传播不在RMI的范围内。

无论您想要远程发生什么,都必须通过远程接口中的方法来定义。