3

我已经使用 Java RMI 建立了一个客户端/服务器项目。下面我展示了部分实现。我使用启动服务器

ProcessBuilder processBuilder = new ProcessBuilder("cmd", "/C", "start /B java -jar myServer.jar --start);
this.myProcess = processBuilder.start();

我已经向处理命令行调用的服务器添加了一个主要方法。服务器启动并完美运行。客户端能够按照我的预期连接和执行。

当我试图杀死服务器时,我的问题就出现了。这需要从外部完成。先前启动该过程的对象不再可用。要真正停止服务器,服务器类的主要方法调用停止方法(见下文)。此方法现在会终止 RMI,但它至少不会阻止 JVM 运行。该进程仍然可用,需要从任务管理器中终止(在 Windows 上)。

我是否错过了在我的实现中产生这种行为的一些事实。为什么进程不会停止运行?

public class MyServer {

    // ...

    public void startServer() throws RemoteException {

        // the RMI registry
        Registry registry;

        try {
            // find the registry
            registry = LocateRegistry.createRegistry(portRMI);
        } catch (Exception e) {
            // if the registry does not yet exist, try to create a new registry
            // entry or use an existing one
            registry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
        }

        // create the object
        servantObject = new MyServant();

        // bind the object to the server
        registry.rebind(MyConstants.SERVER_NAME, servantObject);
    }

    public void stopServer() throws RemoteException {

        try {
            // access the service
            Registry rmiRegistry = LocateRegistry.getRegistry(MyConstants.HOST_NAME, portRMI);
            MyService myService = (MyService) rmiRegistry.lookup(MyConstants.SERVER_NAME);

            rmiRegistry.unbind(MyConstants.SERVER_NAME);

            // get rid of the service object
            UnicastRemoteObject.unexportObject(myService, true);

            // get rid of the rmi registry
            UnicastRemoteObject.unexportObject(rmiRegistry, true);

        } catch (NoSuchObjectException e) {
            // ...
        } catch (NotBoundException e) {
            // ...
        }
    }

    public static void main(String[] args) {
        // handle arguments and call either startServer or stopServer
    }
}

public class MyServant extends UnicastRemoteObject implements MyService {
    // ...
}

public interface MyService extends Remote {
    // ...
}
4

1 回答 1

3

您应该在您的 RMIServer 中添加一个可用的自写 RMIService 接口,以便希望停止正在运行的服务器的程序指示它停止。

您尝试停止服务器的应用程序只是取消绑定某个对象,因为它不是正在运行的 rmi 服务器进程本身,它不会产生很大的影响。

如果您的 rmi 服务器是进程 a,您应该编写一个作为进程 b 运行的应用程序(使用 rmi),以向进程 a 发送消息以停止它。

于 2013-09-13T09:38:35.157 回答