RMI通知服务器更新客户端

4
我正在编写一个虚拟的配送应用。客户端发送一个产品给服务器,服务器会保存所有接收到的产品。
现在,由于服务器是虚拟的,它会每分钟更新一次产品的状态(发送 -> 接受 -> 发货 -> 收到)。我希望当服务器更新了状态时,能够通知相应的客户端。
我发现大多数关于RMI的信息都只涉及客户端向服务器传递信息。但是我需要服务器调用客户端来实现此功能。
希望您能帮忙!
3个回答

8

在所有远程通讯技术中,包括RMI,服务器到客户端的通信都是比较棘手的问题。这也许是为什么你很难找到关于该主题的文档。对于一个受控环境下的示例程序,以下方法将可行且最简单。注意,所有错误处理都已省略。

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

interface ClientRemote extends Remote {
    public void doSomething() throws RemoteException;
}

interface ServerRemote extends Remote {
    public void registerClient(ClientRemote client) throws RemoteException;
}

class Client implements ClientRemote {
    public Client() throws RemoteException {
        UnicastRemoteObject.exportObject(this, 0);
    }

    @Override
    public void doSomething() throws RemoteException {
        System.out.println("Server invoked doSomething()");
    }
}

class Server implements ServerRemote {
    private volatile ClientRemote client;

    public Server() throws RemoteException {
        UnicastRemoteObject.exportObject(this, 0);
    }

    @Override
    public void registerClient(ClientRemote client) throws RemoteException {
        this.client = client;
    }

    public void doSomethingOnClient() throws RemoteException {
        client.doSomething();
    }
}

用法:在服务器上创建一个Server对象,将其添加到您的RMI注册表中,并在客户端上查找它。

还有其他技术可以使客户端通知更加容易,Java Message Service(JMS)通常用于此目的。


当我在服务器上调用doSomethingOnClient()时,我在服务器控制台上得到了"Server invoked doSomething()"而不是客户端控制台!(我还必须让ClientRemote实现Serializable才能使其可运行。)我做错了什么? - Mark Jeronimus
找到问题了。不是将Client对象设置为“Serializable”,而是必须在客户端RMI注册表中注册该对象,并在客户端上启动rmiregistry(因此基本上两侧都是“服务器”)。 - Mark Jeronimus

0

你的客户可能经常向服务器请求并更新自己,或者你可以将客户端编程为RMI服务器,服务器跟踪连接到它的客户端,并在服务器值更改时使用RMI回调客户端。你可以查看SNMP协议,它支持回调(snmp traps)。


0

在我来到这里之前,我已经找到了这个,但是它需要一些奇怪的WLE东西。这不是纯Java。 - Mark Jeronimus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接