Используйте DelimiterBasedFrameDecoder, StringEncoder и т. Д. Вне конвейера в Netty

1

Я использую Netty для разработки TCP-сервера. Я понимаю, что обычное использование заключается в создании ServerBootstrap и передаче объекта Initializer методу childHandler(). В инициализаторе есть метод initChannel, где мы настраиваем конвейер с помощью команды addLast, добавляя такие вещи, как DelimiterBasedFrameDecoder, StringEncoder и т.д. Это предполагает, что мы знаем априорно, что мы всегда будем получать текстовые/строковые сообщения.

Однако я хотел бы реализовать такую возможность, как то, что существует в python Twisted Protocols, например LineReceiver, где мы можем переключаться между режимами raw и line. Да, один из способов сделать это - удалить и добавить элементы из конвейера динамически. Но мне интересно, есть ли веские причины, почему я не мог просто использовать минимальный конвейер, который использует базовый ChannelInitializer, где обработчик является просто расширением ChannelInboundHandlerAdapter. Таким образом метод channelRead в обработчике просто обрабатывает необработанные байты (в ByteBuf). Если я хочу использовать режим линии, не возможно ли мне использовать DelimiterBasedFrameDecoder, StringEncoder и т.д. Внутри метода channelRead, т.е. Вызывать их напрямую и использовать их вне контекста конвейера? Есть ли веская причина, почему я НЕ должен этого делать?

Теги:
netty

2 ответа

0

Простое сравнение:

  • Во-первых, вы должны знать, как работают эти кодеки...
    • Некоторые из них используют контекст, который хранит данные, пока их недостаточно, данные поступают из входящих сообщений (как в DelimiterBasedFrameDecoder).
    • Некоторым нужно, чтобы вы написали дополнительные методы, поэтому ваш способ не мешает вам писать эти дополнительные методы по мере необходимости.
    • Некоторые из них используют контекст обработчика (ChannelHandlerContext), даже если это редко, для хранения некоторых внутренних элементов (сеанс или подобное).
  • Древовидный вызов. Таким образом, вам нужно "вручную" поддерживать одно и то же поведение, передавая правильный аргумент вручную каждому из них (по крайней мере, ChannelHandlerContext). Не уверен, что у вас есть выигрыш. Более того, конвейер сделан эффективным, а не перераспределением, если это не требуется, например.
  • Память: поскольку вам нужно будет создать один на канал (поскольку они не являются совместными, и если они есть, то же самое для конвейера), это такая же стоимость, чем создание одного в конвейере. Так что со стороны памяти, не лучше.
  • Инициализация: добавление/удаление его вручную в/из конвейера, без затрат на поддержание правильного порядка вызова, я считаю проще, чем делать все вручную, выделяя, сохраняя его где-то в атрибуте privatehandhandler.
  • Поведение: некоторые могут полагаться на контекст Netty (ChannelHandlerContext) для правильной работы (например, CompatibleObjectEncoder, MarshallingDecoder). Он будет работать, если это ChannelHandlerContext не строить на Нетти? Не знаю... Но тогда вы должны быть уверены, что кодек действует как ВАС ЗНАЕТ, точно. И если он изменен (потому что внешний API такой же, но способ его модификации и, следовательно, поведение в вашем случае), вы должны знать его или ваш код может потерпеть неудачу, и вы не будете знать, почему...

Поэтому в резюме я не видел никакого преимущества использовать эти коды вручную вместо того, чтобы вставлять/удалять их в конвейер по мере необходимости, но я вижу риск, если внутренняя реализация изменится, пока вы ее не заметили, и она сломает ваш "нестандартный" "логика...

После этого ничего невозможного, поэтому ваш выбор ;-) Но, как отмечено в других комментариях, вы можете написать собственный кодек, вдохновляющий себя на существующие...

0

Можно поместить все логики кодировщиков/декодеров в обработчик, но это плохая идея из точки архитектуры.

Лучше бы написать новый кодек (кодировщик/декодер), возможно, даже на основе их, вы можете посмотреть внутри StringEncoder или StringDecoder или даже на DelimiterBasedFrameDecoder, чтобы понять, как это сделать, на самом деле они довольно просты или проверяют нетто как они реализуют TimeEncoder.

После этого кодек будет иметь возможность тестироваться отдельно, а обработчик и код в целом будут намного яснее.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню