Netty конвертировать HttpRequest в ByteBuf

1

В моем приложении мне нужно получить массив байтов в сокете, проанализировать его как HttpRequest для выполнения некоторой проверки и, если проверки пройдут, вернитесь в массив байтов и выполните еще одну работу.

Приложение основано на NETTY (это требование).

Моя первая идея заключалась в создании такого конвейера:

  1. HttpRequestDecoder (декодирование от ByteBuf до HttpRequest)
  2. MyHttpRequestHandler (делать собственные проверки на HttpRequest)
  3. HttpRequestEncoder (кодирует HttpRequest для ByteBuf)
  4. MyButeBufHandler (делайте мои работы с ByteBuf)

Однако HttpRequestEncoder расширяет ChannelOutboundHandlerAdapter, чтобы он не вызывался для входящих данных.

Как я могу выполнить эту задачу? Было бы неплохо избежать декодирования и повторного кодирования запроса.

С уважением, Массимилиано

Теги:
netty

2 ответа

1
Лучший ответ

Используйте EmbeddedChannel в MyHttpRequestHandler.

EmbeddedChannel ch = new EmbeddedChannel (новый HttpRequestEncoder()); ch.writeOutbound(MSG); ByteBuf encoded = ch.readOutbound();

Вам нужно будет сохранить EmbeddedChannel как переменную-член MyHttpRequestEncoder потому что HttpRequestEncoder имеет состояние. Также, пожалуйста, закройте EmbeddedChannel когда вы закончите использовать его (возможно, в вашем методе channelInactive().)

  • 1
    С этим кодом я получаю сообщение об ошибке: io.netty.handler.codec.EncoderException: java.lang.IllegalStateException: unexpected message type: LastHttpContent$1 at io.netty.handler.codec.MessageToMessageEncoder.write(MessageToMessageEncoder.java:107)
  • 0
    Моя вина. Я забыл оставить EmbeddedChannel в качестве переменной-члена. Теперь это работает. Спасибо!
0

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

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

Я объявлял RequestEncoder и ResponseDecoder как член класса, но он все еще работал неправильно. Пока я не вспомнил, что конкретный обработчик, который я использовал en/decoders внутри, был разделен...

Это то, как я получил его, чтобы работать в конце. Моя последовательностьNr должна различаться между различными запросами. Я создаю один кодировщик и один декодер для каждого запроса и сохраняю их в HashMap. С моей последовательностьюNr я могу всегда получать один и тот же декодер/кодировщик для одного и того же запроса. Не забудьте закрыть и удалить каналы de/encoder с карты после обработки объекта LastContent.

@ChannelHandler.Sharable
public class HttpTunnelingServerHandler extends ChannelDuplexHandler {
private final Map<Integer, EmbeddedChannel> decoders = Collections.synchronizedMap(new HashMap<Integer, EmbeddedChannel>());
private final Map<Integer, EmbeddedChannel> encoders = Collections.synchronizedMap(new HashMap<Integer, EmbeddedChannel>());
.
.
//Encoding
if (!encoders.containsKey(currentResponse.getSequenceNr())) {
        encoders.put(currentResponse.getSequenceNr(), new EmbeddedChannel(new HttpResponseEncoder()));
    }
    EmbeddedChannel encoderChannel = encoders.get(currentResponse.getSequenceNr());
    encoderChannel.writeOutbound(recievedHttpObject);
    ByteBuf encoded = (ByteBuf) encoderChannel.readOutbound();
.
.
//Decoding
if (!decoders.containsKey(sequenceNr)) {
        decoders.put(sequenceNr, new EmbeddedChannel(new HttpRequestDecoder()));
        }
        EmbeddedChannel decoderChannel = decoders.get(sequenceNr);
        decoderChannel.writeInbound(bb);
        HttpObject httpObject = (HttpObject) decoderChannel.readInbound();

}

Ещё вопросы

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