在我的应用程序中,我需要在套接字上接收一个字节数组,将其解析为HttpRequest以执行一些检查,如果检查通过,则返回字节数组并再做一些工作。
该应用程序基于NETTY(这是一项要求)。
我的第一个想法是创建一个这样的管道:
然而,HttpRequestEncoder扩展了ChannelOutboundHandlerAdapter,因此不会为入站数据调用它。
我该如何完成这项任务? 避免解码和重新编码请求会很好。
此致 的Massimiliano
答案 0 :(得分:1)
在EmbeddedChannel
中使用MyHttpRequestHandler
。
EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder()); ch.writeOutbound(MSG); ByteBuf encoded = ch.readOutbound();
您必须将EmbeddedChannel
保留为MyHttpRequestEncoder
的成员变量,因为HttpRequestEncoder
是有状态的。另外,请在使用完毕后关闭EmbeddedChannel
(可能是channelInactive()
方法。)
答案 1 :(得分:0)
我只需对一些HttpObjects进行编码和解码,并对它进行了一些努力。 解码器/编码器有状态的提示非常有价值。
这就是为什么我以为我会在这里添加我的发现。也许这对其他人有帮助。
我将RequestEncoder和ResponseDecoder声明为类成员,但它仍然无法正常工作。直到我记得我使用en / decoders的特定处理程序是共享的......
这就是我最终的工作方式。我的sequenceNr用于区分不同的请求。我为每个请求创建一个编码器和一个解码器,并将它们保存在HashMap中。使用我的sequenceNr,我能够始终为同一请求获得相同的解码器/编码器。处理LastContent对象后,不要忘记关闭并从Map中删除de / encoder通道。
@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();
}
答案 2 :(得分:0)
如何将 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);
}