与RMI进行简单聊天 - 服务器如何在不启动远程异常的情况下停止所有客户端的执行

时间:2015-02-22 16:45:03

标签: java chat rmi

我的Java RMI聊天(客户端 - 服务器类型)存在问题,其中客户端可以“订阅服务器”,这意味着所有客户端引用都存储在服务器上的ArrayList中,所有客户端都可以访问特定命令和一个客户反过来可以成为“特殊”客户。

所有命令都以不同的方式响应,具体取决于客户端是否为“特殊”(简单地说服务器选择一个客户端并将其作为“特殊”将其作为正常存储在ArrayList中,并在名为{的变量中加上{1}}),特别是我的命令有问题!退出:

如果特殊客户端调用cmd!quit,则调用服务器active上的远程方法,然后服务器从ArrayList中删除所有CLIENTS的所有参考,并在ALL上回调siesce(Client reference)客户端之后应该停止执行。

客户端实施变量

abbandona()

客户端方法abbandona()

public class ClientImpl extends UnicastRemoteObject implements Client {
...
private static Server server;        //reference to server
private static ClientImpl client;    //reference to client object (it-self)
...

客户主要

客户端插入调用此部分代码的cmd!quit

public void abbandona() throws RemoteException {         
        System.out.println("Sei stato espulso dalla chat");
        System.exit(0);   
}

服务器实施变量

//start of main and objects creations
...
try {
    server.siesce(client);
} catch (RemoteException e) {
    System.out.println("Esco...");
    System.exit(1);
}
//end of main

服务器方法siesce(客户端参考)

public class ServerImpl extends UnicastRemoteObject implements Server{
...
private static ArrayList<Persona> cli = new ArrayList<Persona>();
       //the Persona object is a wrapper that contains a Client reference and a boolean
       //the client can be taken by calling getCli()
...
private static Client active;  //reference to SPECIAL client

问题在于,在第一个元素上调用第一个public synchronized void siesce(Client ref) throws RemoteException { if (ref.equals(active)) { //checks if the SPECIAL client called this method for (int i=0; i<cli.size(); i++) { try { cli.get(i).getCli().abbandona(); logger.info("..."); } catch (RemoteException e) { logger.severe("..."); } } cli.clear(); //variables reset count = 0; guard = 0; active = null; ready = false; } else { //this else is used when a normal client calls this method ... } } ... 之后检查所有ArrayList元素的循环中它启动了RemoteException(因为客户端退出),它在MAIN代码中被捕获。客户端而不是for循环中的try catch,这会阻止方法继续对其他元素执行此操作,因此只有第一个客户端退出时其他元素不会。

如何让所有客户停止执行?

1 个答案:

答案 0 :(得分:0)

客户端不应退出回调。相反它应该只是(a)取消自身,并(b)在几秒钟之后发布一个布尔值,告诉主线程退出,以允许回调完成。