我正在使用RMI在Java中执行服务器/客户端程序。当服务器崩溃时,这不是问题,客户端会收到RemoteException并断开连接。
但是,当客户端崩溃时,我会遇到问题。我的服务器不时使用Timer来ping所有客户端对象,然后,当它与客户端没有连接时,它将捕获RemoteException。
然后,应该从服务器中删除客户端对象(仅通过从列表中删除客户端对象),但这是不可能的,因为当我尝试对代理客户端对象执行任何操作时,它将抛出另一个RemoteException。我怎么解决这个问题?
List<User> users;
Map<User, IClient> clients;
class PingClients extends TimerTask {
public void run() {
for (IClient client : clients.values())
try {
client.ping();
} catch (RemoteException e) {
//removeClient(client); GENERATES REMOTEEXCEPTION
}
}
}
public boolean removeClient(IClient c) throws RemoteException{
User u = c.getUser();
users.remove(u);
clients.remove(u);
for (IClient client : clients.values())
client.updateUsers(users);
}
最佳答案
之所以得到RemoteException,是因为当您尝试删除客户端(已断开连接)时,首先要在客户端上调用getUser()方法,这显然会引发RemoteException。
您应该将代码更改为以下内容:
class PingClients extends TimerTask {
public void run() {
for (Iterator<Map.Entry<User, IClient>> it = clients.entrySet().iterator(); it.hasNext(); )
Entry<User, IClient> entry = it.next();
try {
IClient client = entry.getValue();
client.ping();
}
catch (RemoteException e) {
it.remove();
}
}
}
确保一次只有一个线程可以访问该 map 。