Note that there are some explanatory texts on larger screens.

plurals
  1. POImplementing keep-alive messages in Netty using WriteTimeoutHandler
    primarykey
    data
    text
    <p>I am using Netty 3.2.7. I am trying to write functionality in my client such that if no messages are written after a certain amount of time (say, 30 seconds), a "keep-alive" message is sent to the server.</p> <p>After some digging, I found that WriteTimeoutHandler should enable me to do this. I found this explanation here: <a href="https://issues.jboss.org/browse/NETTY-79" rel="noreferrer">https://issues.jboss.org/browse/NETTY-79</a>.</p> <p>The example given in the Netty documentation is:</p> <pre><code>public ChannelPipeline getPipeline() { // An example configuration that implements 30-second write timeout: return Channels.pipeline( new WriteTimeoutHandler(timer, 30), // timer must be shared. new MyHandler()); } </code></pre> <p>In my test client, I have done just this. In MyHandler, I also overrided the exceptionCaught() method:</p> <pre><code>public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { if (e.getCause() instanceof WriteTimeoutException) { log.info("Client sending keep alive!"); ChannelBuffer keepAlive = ChannelBuffers.buffer(KEEP_ALIVE_MSG_STR.length()); keepAlive.writeBytes(KEEP_ALIVE_MSG_STR.getBytes()); Channels.write(ctx, Channels.future(e.getChannel()), keepAlive); } } </code></pre> <p>No matter what duration the client does not write anything to the channel, the exceptionCaught() method I have overridden is never called.</p> <p>Looking at the source of WriteTimeoutHandler, its writeRequested() implementation is:</p> <pre><code>public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception { long timeoutMillis = getTimeoutMillis(e); if (timeoutMillis &gt; 0) { // Set timeout only when getTimeoutMillis() returns a positive value. ChannelFuture future = e.getFuture(); final Timeout timeout = timer.newTimeout( new WriteTimeoutTask(ctx, future), timeoutMillis, TimeUnit.MILLISECONDS); future.addListener(new TimeoutCanceller(timeout)); } super.writeRequested(ctx, e); } </code></pre> <p>Here, it seems that this implementation says, "When a write is requested, make a new timeout. When the write succeeds, cancel the timeout."</p> <p>Using a debugger, it does seem that this is what is happening. As soon as the write completes, the timeout is cancelled. This is not the behavior I want. The behavior I want is: "If the client has not written any information to the channel for 30 seconds, throw a WriteTimeoutException."</p> <p>So, is this not what WriteTimeoutHandler is for? This is how I interpreted it from what I've read online, but the implementation does not seem to work this way. Am I using it wrong? Should I use something else? In our Mina version of the same client I am trying to rewrite, I see that the sessionIdle() method is overridden to achieve the behavior I want, but this method is not available in Netty.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload