簡體   English   中英

Netty 將 HttpRequest 轉換為 ByteBuf

[英]Netty convert HttpRequest to ByteBuf

在我的應用程序中,我需要在套接字上接收一個字節數組,將其解析為HttpRequest以執行一些檢查,如果檢查通過,返回到字節數組並做一些更多的工作。

該應用程序基於 NETTY(這是一項要求)。

我的第一個想法是創建一個像這樣的管道:

  1. HttpRequestDecoder (從ByteBuf解碼為HttpRequest
  2. MyHttpRequestHandler (對HttpRequest進行我自己的檢查)
  3. HttpRequestEncoder (將HttpRequest編碼為ByteBuf
  4. MyButeBufHandler (用ByteBuf做我的工作)

但是HttpRequestEncoder擴展了ChannelOutboundHandlerAdapter因此它不會被調用以獲取入站數據。

我怎樣才能完成這個任務? 避免解碼和重新編碼請求會很好。

問候, 馬西米利亞諾

MyHttpRequestHandler使用EmbeddedChannel

EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder()); ch.writeOutbound(msg); ByteBuf 編碼 = ch.readOutbound();

您必須將EmbeddedChannel作為MyHttpRequestEncoder的成員變量,因為HttpRequestEncoder是有狀態的。 另外,請在您使用完EmbeddedChannel后關閉它(可能在您的channelInactive()方法中。)

我只需要對一些 HttpObjects 進行編碼和解碼,並為此苦苦掙扎。 解碼器/編碼器有狀態的提示非常有價值。

這就是為什么我想我會在這里添加我的發現。 也許這對其他人有幫助。

我將 RequestEncoder 和 ResponseDecoder 聲明為類成員,但它仍然無法正常工作。 直到我記得我在其中使用 en/decoders 的特定處理程序是共享的...

這就是我最終讓它工作的方式。 我的 sequenceNr 是為了區分不同的請求。 我為每個請求創建一個編碼器和一個解碼器,並將它們保存在 HashMap 中。 使用我的序列號,我總是能夠為相同的請求獲得相同的解碼器/編碼器。 不要忘記在處理 LastContent 對象后關閉並從 Map 中移除解碼器/編碼器通道。

@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();

}

如何將 EmbeddedChannel 作為處理程序通道的屬性,而不是 HashMap。 與您聲稱解決有狀態編碼器/解碼器的方法不一樣嗎?

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
      ctx.channel().attr(EMBEDED_CH).set( new EmbeddedChannel(new HttpRequestDecoder()));
      super.channelActive(ctx);
}
    
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
      EmbeddedChannel embedCh = ctx.channel().attr(EMBEDED_CH).get();
      if (embedCh != null) {
          embedCh.close();
      }

      super.channelInactive(ctx);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM