Netty中的异常

2025/03/13

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中的异常以及如何在需要时传播异常。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章