Java RMI timeouts (crashes)
I'm doing a server/client program in Java using RMI. When server crashes it's not a problem, clients get a RemoteException and disconnects.
However I have problems when clients crashes. My server uses a Timer to ping all client objects every now and then, when it gets no connection to a client it will catch a RemoteException.
Then, it's supposed to remove the client object from the server (just by removing it from a list), but it's impossible because when I try to do anything with the proxy client object it will throw another RemoteException. How can I solve this problem?
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 cli开发者_运维技巧ent : clients.values())
client.updateUsers(users);
}
You get a RemoteException because when you try to remove the client (which is disconnected), you first call the getUser() method on the client, which obviously throws a RemoteException.
You should change your code to something like this :
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();
}
}
}
Make sure that only one thread has access to the map at a time.
First line, you should use ConcurrentMap instead of a Map. This will avoid you a lot of troubles due to concurrent access to your map.
If IClient c
is your remote object, calling getUser()
on it will obviously throw an exception if the client is unavailable..
精彩评论