我的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,这会阻止方法继续对其他元素执行此操作,因此只有第一个客户端退出时其他元素不会。
如何让所有客户停止执行?
答案 0 :(得分:0)
客户端不应退出回调。相反它应该只是(a)取消自身,并(b)在几秒钟之后发布一个布尔值,告诉主线程退出,以允许回调完成。