[英]Netty convert HttpRequest to ByteBuf
In my application I need to receive a byte array on a socket, parse it as a HttpRequest
to perform some check and, if the checks passes, get back to the byte array and do some more work.在我的应用程序中,我需要在套接字上接收一个字节数组,将其解析为
HttpRequest
以执行一些检查,如果检查通过,返回到字节数组并做一些更多的工作。
The application is based on NETTY (this is a requirement).该应用程序基于 NETTY(这是一项要求)。
My first idea was to create a pipeline like this:我的第一个想法是创建一个像这样的管道:
HttpRequestDecoder
(decode from ByteBuf
to HttpRequest
) HttpRequestDecoder
(从ByteBuf
解码为HttpRequest
)MyHttpRequestHandler
(do my own checks on the HttpRequest
) MyHttpRequestHandler
(对HttpRequest
进行我自己的检查)HttpRequestEncoder
(encode the HttpRequest
to a ByteBuf
) HttpRequestEncoder
(将HttpRequest
编码为ByteBuf
)MyButeBufHandler
(do my works with the ByteBuf
) MyButeBufHandler
(用ByteBuf
做我的工作) However the HttpRequestEncoder
extends the ChannelOutboundHandlerAdapter
so it doesn't get called for the inbound data.但是
HttpRequestEncoder
扩展了ChannelOutboundHandlerAdapter
因此它不会被调用以获取入站数据。
How can I accomplish this task?我怎样才能完成这个任务? It would be nice to avoid decoding and re-encoding the request.
避免解码和重新编码请求会很好。
Regards, Massimiliano问候, 马西米利亚诺
Use an EmbeddedChannel
in MyHttpRequestHandler
.在
MyHttpRequestHandler
使用EmbeddedChannel
。
EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder()); EmbeddedChannel ch = new EmbeddedChannel(new HttpRequestEncoder()); ch.writeOutbound(msg);
ch.writeOutbound(msg); ByteBuf encoded = ch.readOutbound();
ByteBuf 编码 = ch.readOutbound();
You'll have to keep the EmbeddedChannel
as a member variable of MyHttpRequestEncoder
because HttpRequestEncoder
is stateful.您必须将
EmbeddedChannel
作为MyHttpRequestEncoder
的成员变量,因为HttpRequestEncoder
是有状态的。 Also, please close the EmbeddedChannel
when you finished using it (probably in your channelInactive()
method.)另外,请在您使用完
EmbeddedChannel
后关闭它(可能在您的channelInactive()
方法中。)
I just had to encode and decode some HttpObjects and struggled a bit with it.我只需要对一些 HttpObjects 进行编码和解码,并为此苦苦挣扎。 The hint that the decoder/encoder are stateful is very valuable.
解码器/编码器有状态的提示非常有价值。
That's why I thought I'll add my findings here.这就是为什么我想我会在这里添加我的发现。 Maybe it's helpful to someone else.
也许这对其他人有帮助。
I declared an RequestEncoder and a ResponseDecoder as a class member, but it still didn't work correctly.我将 RequestEncoder 和 ResponseDecoder 声明为类成员,但它仍然无法正常工作。 Until I remembered that the specific handler I was using the en/decoders within was shared...
直到我记得我在其中使用 en/decoders 的特定处理程序是共享的...
That's how I got it to work in the end.这就是我最终让它工作的方式。 My sequenceNr is to distinct between the different requests.
我的 sequenceNr 是为了区分不同的请求。 I create one encoder and one decoder per request and save them in a HashMap.
我为每个请求创建一个编码器和一个解码器,并将它们保存在 HashMap 中。 With my sequenceNr, I'm able to always get the same decoder/encoder for the same request.
使用我的序列号,我总是能够为相同的请求获得相同的解码器/编码器。 Don't forget to close and remove the de/encoder channels from the Map after processing the LastContent object.
不要忘记在处理 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();
}
How about the put the EmbeddedChannel as the handler channel's attribute, instead of HashMap.如何将 EmbeddedChannel 作为处理程序通道的属性,而不是 HashMap。 Isn't it the same what you claim to solve the stateful encoder/decoder?
与您声称解决有状态编码器/解码器的方法不一样吗?
@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.