La mise en œuvre de keep-alive messages dans Netty à l'aide de WriteTimeoutHandler
Je suis en utilisant Netty 3.2.7. Je suis en train d'écrire la fonctionnalité dans mon client de façon à ce que si aucun message n'est écrit d'après un certain laps de temps (par exemple, 30 secondes), un "keep-alive" message est envoyé au serveur.
Après quelques recherches, j'ai trouvé que WriteTimeoutHandler devrait me permettre de faire cela. J'ai trouvé cette explication ici: https://issues.jboss.org/browse/NETTY-79.
L'exemple donné dans la Netty documentation:
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());
}
Dans mon client de test, j'ai fait tout cela. Dans MyHandler, j'ai aussi surdéfini la exceptionCaught() méthode:
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);
}
}
N'importe quelle durée, le client ne rien écrire sur le canal, le exceptionCaught() méthode que j'ai remplacé n'est jamais appelée.
Regardant le source de WriteTimeoutHandler, son writeRequested() de la mise en œuvre est:
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);
}
Ici, il semble que cette mise en œuvre a dit, "Quand une demande d'écriture, de faire un nouveau délai d'attente. Lors de l'écriture réussit, d'annuler le délai d'attente."
À l'aide d'un débogueur, il semble que c'est ce qui se passe. Dès que l'écriture est terminée, le délai d'attente est annulée. Ce n'est pas le comportement que je veux. Le comportement que je veux c'est: "Si le client n'a pas écrit de toutes les informations au canal pendant 30 secondes, jeter un WriteTimeoutException."
Donc, n'est-ce pas ce que WriteTimeoutHandler est-ce? C'est ainsi que j'ai interprété à partir de ce que j'ai lu en ligne, mais la mise en œuvre ne semble pas fonctionner de cette façon. Suis-je à l'aide de ce mal? Dois-je utiliser autre chose? Dans notre Mina version d'un même client, je suis en train de réécrire, je vois que le sessionIdle() la méthode est substituée pour obtenir le comportement que je veux, mais cette méthode n'est pas disponible dans Netty.
OriginalL'auteur ImmuneEntity | 2012-02-01
Vous devez vous connecter pour publier un commentaire.
Je suggère d'ajouter la IdleStateHandler et puis ajouter votre personnalisé de mise en œuvre de IdleStateAwareUpstreamHandler qui peut réagir sur l'état inactif. Cela fonctionne très bien pour moi sur de nombreux projets différents.
La javadoc de la liste de l'exemple suivant, que vous pouvez utiliser comme base de votre mise en œuvre:
Docs ont déménagé à IdleStateHandler.html, IdleStateAwareChannelHandler.html
OriginalL'auteur Norman Maurer
Pour Netty 4.0 et plus récent, vous devez étendre ChannelDuplexHandler comme dans l'exemple de IdleStateHandler documentation :
OriginalL'auteur user11153