Я использую Netty для разработки TCP-сервера. Я понимаю, что обычное использование заключается в создании ServerBootstrap и передаче объекта Initializer методу childHandler(). В инициализаторе есть метод initChannel, где мы настраиваем конвейер с помощью команды addLast, добавляя такие вещи, как DelimiterBasedFrameDecoder, StringEncoder и т.д. Это предполагает, что мы знаем априорно, что мы всегда будем получать текстовые/строковые сообщения.
Однако я хотел бы реализовать такую возможность, как то, что существует в python Twisted Protocols, например LineReceiver, где мы можем переключаться между режимами raw и line. Да, один из способов сделать это - удалить и добавить элементы из конвейера динамически. Но мне интересно, есть ли веские причины, почему я не мог просто использовать минимальный конвейер, который использует базовый ChannelInitializer, где обработчик является просто расширением ChannelInboundHandlerAdapter. Таким образом метод channelRead в обработчике просто обрабатывает необработанные байты (в ByteBuf). Если я хочу использовать режим линии, не возможно ли мне использовать DelimiterBasedFrameDecoder, StringEncoder и т.д. Внутри метода channelRead, т.е. Вызывать их напрямую и использовать их вне контекста конвейера? Есть ли веская причина, почему я НЕ должен этого делать?
Простое сравнение:
DelimiterBasedFrameDecoder
).ChannelHandlerContext
), даже если это редко, для хранения некоторых внутренних элементов (сеанс или подобное).ChannelHandlerContext
). Не уверен, что у вас есть выигрыш. Более того, конвейер сделан эффективным, а не перераспределением, если это не требуется, например.ChannelHandlerContext
) для правильной работы (например, CompatibleObjectEncoder
, MarshallingDecoder
). Он будет работать, если это ChannelHandlerContext
не строить на Нетти? Не знаю... Но тогда вы должны быть уверены, что кодек действует как ВАС ЗНАЕТ, точно. И если он изменен (потому что внешний API такой же, но способ его модификации и, следовательно, поведение в вашем случае), вы должны знать его или ваш код может потерпеть неудачу, и вы не будете знать, почему...Поэтому в резюме я не видел никакого преимущества использовать эти коды вручную вместо того, чтобы вставлять/удалять их в конвейер по мере необходимости, но я вижу риск, если внутренняя реализация изменится, пока вы ее не заметили, и она сломает ваш "нестандартный" "логика...
После этого ничего невозможного, поэтому ваш выбор ;-) Но, как отмечено в других комментариях, вы можете написать собственный кодек, вдохновляющий себя на существующие...
Можно поместить все логики кодировщиков/декодеров в обработчик, но это плохая идея из точки архитектуры.
Лучше бы написать новый кодек (кодировщик/декодер), возможно, даже на основе их, вы можете посмотреть внутри StringEncoder или StringDecoder или даже на DelimiterBasedFrameDecoder, чтобы понять, как это сделать, на самом деле они довольно просты или проверяют нетто как они реализуют TimeEncoder.
После этого кодек будет иметь возможность тестироваться отдельно, а обработчик и код в целом будут намного яснее.