2

I am building a client-server application where I have to implement a keepalive mechanism in order to detect that the client has crashed or not. I have separate threads on both client and server side. the client thread sends a "ping" then sleeps for 3 seconds, while the server reads the BufferedInputStream and checks whether ping is received, if so it makes the ping counter equals zero, else it increments the counter by +1, the server thread then sleeps for 3 seconds, if the ping counter reaches 3, it declares the client as dead.

The problem is that when the server reads the input stream, its a blocking call, and it blocks until the next ping is received, irrespective of how delayed it is, so the server never detects a missed ping.

any suggestions, so that I can read the current value of the stream and it doesn't block if there is nothing on the incoming stream.

Thanks,

Donato Szilagyi
  • 4,279
  • 4
  • 36
  • 53
comatose
  • 1,952
  • 7
  • 26
  • 42
  • Can you please explain "server never detects a missed ping"? – The Scrum Meister Dec 30 '10 at 16:50
  • Say for example the client is sending keep-alives every 3 seconds, and the server is also checking for keep-alives every 3 seconds. Now say the client doesn't send a keep-alive for 10 seconds, then when the server will check for the keep-alive, it wont read anything, coz the client sent nothing, so the call to read from stream will block untill it receives the next keepalive 10 seconds later at which point the server will gladly declare that it received a keepalive. So it will never detect a lost keep-alive. – comatose Dec 31 '10 at 01:50

2 Answers2

5

Java 1.4 introduced the idea of non-blocking I/O, represented by the java.nio package. This is probably what you need.

See this tutorial for how to use non-blocking I/O.

Also, assuming this isn't homework or a learning exercise, then I recommend using a more robust protocol framework such as Apache Mina or JBoss Netty, rather than building this stuff from scratch. See this comparison between them, and why you'd want to use them.

Community
  • 1
  • 1
skaffman
  • 398,947
  • 96
  • 818
  • 769
0

You can have a separate monitoring thread which monitors all the blocking connections. When a connection receives anything it can reset a counter. (I would treat any packet as good as a heartbeat) Your monitoring thread can increment this counter each times it runs and when it reaches a limit (i.e. because it wasn't reset back to zero) you can close the connection. You only need one such thread. The thread which is blocking on the connection you just closed with throw an IOException, waking the thread.

On the other side, a heartbeat can be triggered whenever a packet has not been sent for some period of time. This mean a busy connection doesn't send any heartbeats, it shouldn't need to.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130