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

时间:2013-12-20 12:45:42

标签: java rmi remote-access

我正在尝试使用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来获取更新的值,但我打算使用此方法为服务器实现多播功能。

任何人都可以解释原因吗?如果我需要这样做,那么这样做的方式是什么?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

干杯