Исключения в Netty

Исключения в 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.