Java RMI - Client Timeout
Asked Answered
A

4

13

I'm building a Distributed System using Java RMI and it must support a server loss.

If my client is connected to a Server using RMI, if this server goes down (cable problems for example), my client should get an exception so it can connect to other server.

But when the server goes down, nothing happens to my client, he keeps waiting for the reply. How can I set a timeout for that?

Affairs answered 30/11, 2009 at 22:1 Comment(0)
S
16

For socket read timeout, you can set your own factory like this,

           RMISocketFactory.setSocketFactory( new RMISocketFactory()
            {
                public Socket createSocket( String host, int port )
                    throws IOException
                {
                    Socket socket = new Socket();
                    socket.setSoTimeout( timeoutMillis );
                    socket.setSoLinger( false, 0 );
                    socket.connect( new InetSocketAddress( host, port ), timeoutMillis );
                    return socket;
                }

                public ServerSocket createServerSocket( int port )
                    throws IOException
                {
                    return new ServerSocket( port );
                }
            } );
Sticky answered 30/11, 2009 at 22:12 Comment(6)
what an ugly hack! See @Noky's answer below with a property based approach.Metaphysical
Setting socket factories statically has been obsolete since 1998, and breaks things like RMI/SSL. And don't mess around with SO_LINGER. In this case you are just asserting the default, which is pointless, but it's an invitation to some later hacker to change it.Rebarebah
@EJP, can you elaborate on that, or at least add some reading references? How might statically setting socket factories break RMI/SSL?Livvi
Because RMI/SSL relies on R,IServerSocketFactory and RMIClientSocketFactory, the non-static RMI socket factory interfaces.Rebarebah
Hmmm... where is timeoutMillis declared? Is its declaration in scope of the method within which the anonymous inner subclass of RMISocketFactory is being created?Towering
In the above quoted code, the time-out is specified in the setSoTimeout method and in the connect method. Does it really have to be specified twice?Towering
S
13

I recently encountered this problem as well and found that I needed to set the following Java property in order for an RMI call to timeout on the client side:

sun.rmi.transport.tcp.responseTimeout

Here is the full scoop on these params in newer versions of Java:

Seneca answered 16/10, 2012 at 18:57 Comment(0)
D
9

There is a system property that you can set.
Something like sun.rmi.transport.connectionTimeout

They are detailed here:
https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/sunrmiproperties.html

Dandiprat answered 30/11, 2009 at 22:4 Comment(3)
I was thinking that it could be the sun.rmi.transport.connectionTimeout. But the defaulf value is 15 seconds. My client keeps waiting for the reply for minutes.. =/Affairs
"These properties are not part of the RMI public API"Antifriction
I use the following, some of these properties have 2 hour default! -Dsun.rmi.transport.connectionTimeout=5000 -Dsun.rmi.transport.tcp.handshakeTimeout=5000 -Dsun.rmi.transport.tcp.responseTimeout=5000 -Dsun.rmi.transport.tcp.readTimeout=5000Metaphysical
A
0

You can use custom socket factories. It works fine , It is not static and deprecated and against the system property, it does not apply to the whole JVM. But the point is that the code is on the server side.

Creating a Custom RMI Socket Factory

Akene answered 28/10, 2018 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.