1. 概述
在这篇简短的文章中,我们将研究Netty中的异常处理。
简单来说,Netty是一个用于构建高性能异步和事件驱动的网络应用程序的框架,在其生命周期内使用回调方法处理I/O操作。
关于该框架的更多细节以及如何开始使用它,请参阅我们之前的文章。
2. Netty中的异常处理
前面提到过,Netty是一个事件驱动的系统,有针对特定事件的回调方法;异常也是这样的事件。
处理从客户端收到的数据或执行I/O操作时可能会发生异常,发生这种情况时,会触发专用的异常捕获事件。
2.1 处理源通道中的异常
当触发异常捕获事件时,该事件由ChannelInboundHandler或其适配器和子类的exceptionsCaught()方法处理。
请注意,ChannelHandler接口中的回调已被弃用,它现在仅限于ChannelInboundHandler接口。
该方法接收一个Throwable对象和一个ChannelHandlerContext对象作为参数,Throwable对象可用于打印堆栈跟踪或获取本地化错误消息。
因此让我们创建一个通道处理程序ChannelHandlerA并用我们的实现覆盖其exceptionCaught():
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.info(cause.getLocalizedMessage());
//do more exception handling
ctx.close();
}
在上面的代码片段中,我们记录了异常消息并调用了ChannelHandlerContext的close()。
这将关闭服务器和客户端之间的通道,本质上导致客户端断开连接并终止。
2.2 传播异常
在上一节中,我们在异常的来源通道中处理了异常。但是,我们实际上可以将异常传播到管道中的另一个通道处理程序。
我们不记录错误消息并调用ctx.close(),而是使用ChannelHandlerContext对象手动触发另一个异常捕获事件。
这将导致调用管道中的下一个通道处理程序的exceptionCaught()。
让我们修改ChannelHandlerA中的代码片段,通过调用ctx.fireExceptionCaught()来传播事件:
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.info("Exception Occurred in ChannelHandler A");
ctx.fireExceptionCaught(cause);
}
此外,让我们创建另一个通道处理程序ChannelHandlerB并用以下实现覆盖其exceptionCaught() :
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.info("Exception Handled in ChannelHandler B");
logger.info(cause.getLocalizedMessage());
//do more exception handling
ctx.close();
}
在Server类中,通道按照以下顺序添加到管道中:
ch.pipeline().addLast(new ChannelHandlerA(), new ChannelHandlerB());
当所有异常都由一个指定的通道处理程序处理时,手动传播捕获的异常事件很有用。
3. 总结
在本教程中,我们研究了如何使用回调方法处理Netty中的异常以及如何在需要时传播异常。
Post Directory
