abcast
asked on
rmi timeouts
How can I set a timeout for RMI clients so that they do not wait seemingly forever when attempting to contact a dead server?
ASKER
...but if the server is unresponsive, I still have a client, which is consuming a thread, that is stuck waiting for a timeout for an undetermined amount of time. Isn't there some sort of timeout property for RMI that actually works?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Or you could try something like what they discuss here
http://www.jguru.com/faq/view.jsp?EID=332524
http://www.jguru.com/faq/view.jsp?EID=332524
>> when attempting to contact a dead server
If the server is down, connecting would throw an exception.
If the server is down, connecting would throw an exception.
ASKER
>>If the server is down, connecting would throw an exception.
In a perfect world, yes. In reality, no.
In a perfect world, yes. In reality, no.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
>>It depends on your network configuration - if the network time out value is large then it will take some time, but sooner or later it has to throw.
True. But the time to timeout has been variable in practice. Up to several hours. This is a problem for me.
True. But the time to timeout has been variable in practice. Up to several hours. This is a problem for me.
Try the Socket.connect () method overload which takes a timeout parameter:
http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html
http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html
ASKER
How do I expose a socket object when calling a remote method on an RMI server?
You can create your own factory:
RMISocketFactory.setSocket Factory ( new RMISocketFactory () {
public Socket createSocket ( String host, int port ) throws IOException
{
Socket socket = new Socket ( host, port ) ;
socket.setSoTimeout ( timeoutMillis ) ;
socket.setSoLinger ( false, 0 ) ;
return socket ;
}
public ServerSocket createServerSocket ( int port ) throws IOException
{
return new ServerSocket ( port ) ;
}
} ) ;
RMISocketFactory.setSocket
public Socket createSocket ( String host, int port ) throws IOException
{
Socket socket = new Socket ( host, port ) ;
socket.setSoTimeout ( timeoutMillis ) ;
socket.setSoLinger ( false, 0 ) ;
return socket ;
}
public ServerSocket createServerSocket ( int port ) throws IOException
{
return new ServerSocket ( port ) ;
}
} ) ;
Or you can try setting the "sun.rmi.transport.tcp.rea dTimeout" property.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Date lastContactCheck = new Date();
Then what you would do is create a simple thread that checks how long it has been since it last updated.
public class CheckThread extends Thread {
public void run() {
while (true) {
Date date = new Date();
// start looping through Clients and grabbing the lastCheckDate
if(date.getTime() - lastContactCheck.getTime()
// notify User or log them out
}
// end loop
try {
sleep(60000); // sleep for a minute
}
catch(InterruptedException
// Do something about exception
}
}
}
}
// Then on your server have a method that would actually update the lastCheckDate
public synchronized void updateCheckDate(int client_id) throws Exception {
// retrieve the object for that client and update it
lastCheckDate = new java.util.Date();
}
// start the CheckThread on the server when you start the server
CheckThread check = new CheckThread();
check.start();
// Now you need to create a thread for the client to periodically call the method to update the lastCheckDate
public class updateCheckDateThread extends Thread{
public updateCheckDateThread() {
super();
}
public void run() {
while (true) {
try {
// call updateCheckDate method on server
} catch (Exception e) {
// do something with exception
}
try {
sleep(30000); // sleep for 30 seconds or so
} catch (InterruptedException ex) {
// do something with the exception
}
}
}
}
// Now just simply start the thread when the client logs in
updateCheckDateThread updatecheck = new updateCheckDateThread();
updatecheck.start()
Basically, what this will do is for each Client that starts it will update the date by calling a method on the server. if the server doesn't update the date then you have a dead server. You would just need to set the times that are best for your application