Sto utilizzando Netty 3.2.7. Sto cercando di scrivere funzionalità nel mio client in modo tale che se nessun messaggio viene scritto dopo un certo periodo di tempo (diciamo 30 secondi), un messaggio "keep-alive" viene inviato al server.Implementazione di messaggi keep-alive in Netty utilizzando WriteTimeoutHandler
Dopo alcuni scavi, ho scoperto che WriteTimeoutHandler dovrebbe consentirmi di farlo. Ho trovato questa spiegazione qui: https://issues.jboss.org/browse/NETTY-79.
L'esempio riportato nella documentazione di Netty è:
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());
}
Nel mio client di prova, mi hanno fatto proprio questo. In MyHandler, ho anche overrided il metodo exceptionCaught():
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);
}
}
Non importa quale sia la durata il cliente non scrive nulla al canale, il metodo exceptionCaught() ho sovrascritto non viene mai chiamato.
Guardando la fonte della WriteTimeoutHandler, la sua attuazione writeRequested() è:
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e)
throws Exception {
long timeoutMillis = getTimeoutMillis(e);
if (timeoutMillis > 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);
}
Qui, sembra che questa implementazione dice: "Quando si richiede una scrittura, fare un nuovo timeout Quando succede al di scrittura. , annulla il timeout. "
Utilizzando un debugger, sembra che questo sia ciò che sta accadendo. Non appena la scrittura termina, il timeout viene cancellato. Questo non è il comportamento che voglio. Il comportamento che voglio è: "Se il client non ha scritto alcuna informazione sul canale per 30 secondi, lancia una WriteTimeoutException."
Quindi, questo non è ciò per cui WriteTimeoutHandler? È così che l'ho interpretato da ciò che ho letto online, ma l'implementazione non sembra funzionare in questo modo. Sto usando male? Dovrei usare qualcos'altro? Nella nostra versione Mina dello stesso client che sto cercando di riscrivere, vedo che il metodo sessionIdle() viene sovrascritto per ottenere il comportamento che voglio, ma questo metodo non è disponibile in Netty.
Sono stato in grado di implementare le modifiche suggerite in meno di dieci minuti e funziona perfettamente. Grazie Signore! – ImmuneEntity
I documenti sono stati spostati in [IdleStateHandler.html] (http://static.netty.io/3.6/api/org/jboss/netty/handler/timeout/IdleStateHandler.html), [IdleStateAwareChannelHandler.html] (http: // static.netty.io/3.6/api/org/jboss/netty/handler/timeout/IdleStateAwareChannelHandler.html) – mxro