我正在尝试使用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) {
c.x = 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: " + x.x);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
我的问题是,即使我在服务器端更新对象c中的x
的值,它也不会反映到客户端。我只是可以使用return
来获取更新的值,但我打算使用此方法为服务器实现多播功能。
任何人都可以解释原因吗?如果我需要这样做,那么这样做的方式是什么?
答案 0 :(得分:1)
RMI并不神奇。它是远程方法调用。您必须调用远程方法才能在远程位置发生某些事情。只是更改变量并使其在网络中神奇地传播不属于RMI范围。
无论您想远程发生什么,都必须通过远程接口中的方法来定义。
答案 1 :(得分:1)
当您使用RMI时,您在给定计算中涉及2个(或更多)Java虚拟机,因此当您在客户端创建对象并在服务器上调用方法时,将此对象作为参数传递对象被序列化并通过网络发送。在服务器端,创建同一类的新对象并在其上设置状态,但它是一个具有相同值的不同对象。在此克隆上操作不会反映仍驻留在源虚拟机上的原始对象。
您必须在运行虚拟机的每台计算机上使用rmiregistry并注册每个对象以公开它(这是一个分布式解决方案),或者您可以将所有数据对象集中在具有rmiregistry的计算机上(这是集中式解决方案,因为所有对象都在同一台机器上。)
干杯