Исключения в Netty
1. обзор
В этой быстрой статье мы рассмотрим обработку исключений в Netty.
Проще говоря, Netty - это платформа для создания высокопроизводительных асинхронных и управляемых событиями сетевых приложений. I/O operations are handled inside its life-cycle using callback methods.
Более подробную информацию о фреймворке и о том, как начать работу с ним, можно найти в наших предыдущихarticle here.
2. Обработка исключений в Netty
Как упоминалось ранее,Netty is an event-driven system and has callback methods for specific events. Exceptions are such events too.
Исключения могут возникать при обработке данных, полученных от клиента, или во время операций ввода-вывода. Когда это происходит, запускается выделенное исключенное событие.
2.1. Обработка исключений в канале происхождения
The exception-caught event, when fired, is handled by the exceptionsCaught() methodChannelInboundHandler или его адаптеров и подклассов.
Обратите внимание, что обратный вызов устарел в интерфейсеChannelHandler. Теперь он ограничен интерфейсомChannelInboudHandler.
Метод принимает в качестве параметров объектThrowable и объектChannelHandlerContext. ОбъектThrowable можно использовать для печати трассировки стека или получения локализованного сообщения об ошибке.
Итак, давайте создадим обработчик каналаChannelHandlerA и заменим егоexceptionCaught() нашей реализацией:
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
logger.info(cause.getLocalizedMessage());
//do more exception handling
ctx.close();
}
В приведенном выше фрагменте кода мы зарегистрировали сообщение об исключении, а также вызывалиclose() изChannelHandlerContext.
Это закроет канал между сервером и клиентом. По сути, заставляя клиента отключиться и прекратить работу.
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 с помощью метода обратного вызова и как при необходимости распространять исключения.
Доступен полный исходный кодover on Github.