您可以在管道的顶部/尾部只有一个入站和出站异常处理程序。如果您想捕获所有异常,则可以执行以下操作(我假设这是Netty 4.0):
import io.netty.channel.*;import java.net.SocketAddress;public class ExceptionHandler extends ChannelDuplexHandler { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // Uncaught exceptions from inbound handlers will propagate up to this handler } @Override public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) { ctx.connect(remoteAddress, localAddress, promise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (!future.isSuccess()) { // Handle connect exception here... } } })); } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) { ctx.write(msg, promise.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (!future.isSuccess()) { // Handle write exception here... } } })); } // ... override more outbound methods to handle their exceptions as well}入站处理程序引发的任何异常都将“向上”传播到管道中并调用此处理程序的
exceptionCaught()方法,前提是下面的处理程序不使用它们。
对于像出站操作
write()和
connect(),你需要添加一个
ChannelFutureListener吸引他们的异常。
该
exceptionCaught()方法只调用的例外,从入站事件一样
channelRead(),
channelActive()等等。
通过将此处理程序置于管道的“顶部”,我们可以捕获下面所有出站处理程序的异常。假设您的出站处理程序中的一个正在执行某种编码,但此操作失败并例外,这将由我们添加到该
write()操作的Promise中的通道将来的侦听器处理。
如果此异常处理程序像您最初建议的那样安装在管道的“底部”
/头部,则它将看不到来自其上方处理程序的异常,因为
write()如果在先前的处理程序中写入失败,则永远不会调用其方法。这就是为什么此处理程序必须位于顶部的原因。
为了希望避免对管道顶部/底部的混淆,这是我如何配置示例管道:
pipeline.addLast(outboundHandler2) // bottom .addLast(outboundHandler1) .addLast(inboundHandler2) .addLast(inboundHandler1) .addLast(new ExceptionHandler()); // top



