[英]Netty convert HttpRequest to ByteBuf
在我的应用程序中,我需要在套接字上接收一个字节数组,将其解析为HttpRequest
以执行一些检查,如果检查通过,返回到字节数组并做一些更多的工作。
该应用程序基于 NETTY(这是一项要求)。
我的第一个想法是创建一个像这样的管道:
HttpRequestDecoder
(从ByteBuf
解码为HttpRequest
)MyHttpRequestHandler
(对HttpRequest
进行我自己的检查)HttpRequestEncoder
(将HttpRequest
编码为ByteBuf
)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.