#netty #netty4
#netty #netty4
Вопрос:
Я заметил, что при использовании Netty можно записывать другие данные, которые являются экземпляром ByteBuff
или простыми объектами Java.
Как видно из HAProxyClient
В этом файле у вас есть
HAProxyMessage message = new HAProxyMessage(
HAProxyProtocolVersion.V2,
HAProxyCommand.PROXY, HAProxyProxiedProtocol.TCP4,
"127.0.0.1",
"127.0.0.2",
8000,
9000
);
ch.writeAndFlush(message).sync();
Где обычный объект Java, HAProxyMessage
был записан в контекст. Все еще в том же файле у вас есть:
ch.writeAndFlush(Unpooled.copiedBuffer("Hello World!", CharsetUtil.US_ASCII)).sync();
Где Unpooled.copiedBuffer
используется для создания данных, подлежащих записи. Этот метод возвращает a ByteBuf
.
Тогда возникает вопрос: какова существенная разница (если таковая имеется) между записью (или чтением) объекта plan Java и ByteBuf
Ответ №1:
Когда вы пишете ByteBuf, сообщение не нуждается в каком-либо преобразовании. Когда это объект Java, вам нужен кодировщик / декодер. Здесь у вас есть следующее:
- Кодировщик: https://github.com/netty/netty/blob/a60825c3b425892af9be3e9284677aa8a58faa6b/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageEncoder.java
- Декодер: https://github.com/netty/netty/blob/a60825c3b425892af9be3e9284677aa8a58faa6b/codec-haproxy/src/main/java/io/netty/handler/codec/haproxy/HAProxyMessageDecoder.java
Они преобразуют объект Java в ByteBuf (кодировщик) или наоборот (декодер).
Способ, которым вы хотите использовать тот или иной, зависит от вашего текущего случая:
- управляете ли вы объектом Java? Вероятно, наличие кодека (Encoder / Decodec) — хороший способ.
- управляете ли вы простыми данными (байтовым потоком, простыми значениями …)? Вероятно, прямое управление ByteBuf — хороший способ. Это не единственные актуальные вопросы, которые нужно решать для того или другого.
Но, наконец, в Netty все является ByteBuf.
Комментарии:
1. Я понимаю. Следовательно, если мне нужно сказать, напишите что-то вроде новой строки. Вероятно, было бы эффективнее превратить это в массив byte[], чем обернуть его в ByteBuf? или нет?
2. Огромным преимуществом ByteBuf является его способность накапливать различные источники. Например, из массива байтов, используя обернутый ByteBuf, и для добавления нескольких байтов, используя составной ByteBuf, или reverseley для создания ByteBuf с вероятным конечным размером и записи всего в него. Основная идея состоит в том, чтобы ограничить как можно большее копирование памяти, поэтому, в общем, обертывание и использование композиции ByteBufs являются лучшими. Но, как правило, это означает, что, конечно, есть исключения. Внутренне Netty нуждается в ByteBuf, поэтому какой бы объект Java вы ни использовали (даже массив байтов), в конечном итоге придется обратиться к ByteBuf.
3. Спасибо за ответ. Я знаю, что существуют разные реализации ByteBuf. Вы случайно не знаете, какой по умолчанию использует Netty internally…so пример в случае, когда записывается что-то такое простое, как byte[] ?
4. Это действительно зависит от протокола. Например, когда размер уже известен и сообщение создается из разных источников, ByteBuf выделяется один раз и записывается из разных источников (это, как правило, имеет непрерывный внутренний массив байтов, поэтому более эффективно, но ценой нескольких копий). Другой пример — когда исходный код ограничен массивом в один байт (или более, как в вашем примере), для предотвращения копирования мы используем wrappedBuffers(array1, array2, array3), который, как правило, ограничивает копирование по цене, не связанной с непрерывным доступом к памяти. Однако, наконец, все должно быть ByteBuf.
5. Кроме того, Netty использует мощный и эффективный алгоритм для выделения памяти, повторного использования, буферизации, поэтому причина ByteBuf. Если у вас есть только один байтовый массив (или 2, один для реальных данных, другой, фиксированный, для » n».getBytes() , вы можете использовать wrappedBuffers . Но если у вас есть возможность встроить этот массив байтов непосредственно в ByteBuf, это может быть даже лучше, поскольку «ваш» массив байтов, следовательно, не управляется пулом памяти Netty при его переносе.