Reputation: 2765
The situation: DelimiterBasedFrameDecoder extends ByteToMessageDecoder
, and ByteToMessageDecoder
does keep the unprocessed bytes in a ByteBuf
called cumulation
.
I'd like to manually call this handler inside another handler to empty this cumulation
ByteBuf
.
What I tried:
DelimiterBasedFrameDecoder frameDecoder = (DelimiterBasedFrameDecoder) inboundChannel.pipeline().get("frameDecoder");
frameDecoder.channelRead(ctx, Unpooled.EMPTY_BUFFER);
The problem: What I tried doesn't work because there's no next handler so Netty tells me that the bytes are lost:
Discarded inbound message UnpooledHeapByteBuf(ridx: 0, widx: 57, cap: 57) that reached at the tail of the pipeline. Please check your pipeline configuration.
Upvotes: 0
Views: 1321
Reputation: 2765
Norman put me on the right track but here's what I needed to do in my case:
PublicCumulationDelimiterBasedFrameDecoder frameDecoder = (PublicCumulationDelimiterBasedFrameDecoder) cp.get("frameDecoder");
ByteBuf bytesNotProcessed = frameDecoder.internalBuffer();
if (bytesNotProcessed != Unpooled.EMPTY_BUFFER) { PublicCumulationDelimiterBasedFrameDecoder tmpDelimiterBasedFrameDecoder = new PublicCumulationDelimiterBasedFrameDecoder(2048, false, true, Unpooled.wrappedBuffer(new byte[] { 0x03 }));
EmbeddedChannel ec = new EmbeddedChannel(tmpDelimiterBasedFrameDecoder, ... other handlers...);
ByteBuf wrapper = Unpooled.buffer();
wrapper.writeBytes(bytesNotProcessed);
ec.writeInbound(wrapper);// make it process the bytes
// put the remaining bytes (if any) back into the original buffer
bytesNotProcessed.clear();
bytesNotProcessed.writeBytes(tmpDelimiterBasedFrameDecoder.internalBuffer());
}
where PublicCumulationDelimiterBasedFrameDecoder
is just this:
public class PublicCumulationDelimiterBasedFrameDecoder extends DelimiterBasedFrameDecoder {
public PublicCumulationDelimiterBasedFrameDecoder(int maxFrameLength, boolean stripDelimiter, boolean failFast, ByteBuf delimiter) {
super(maxFrameLength, stripDelimiter, failFast, delimiter);
}
public ByteBuf internalBuffer() {
return super.internalBuffer();
}
}
Upvotes: 0
Reputation: 23567
You can wrap your handler in a EmbeddedChannel and use writeInbound() and readInbound(). Check our unit tests for usage examples and also the javadocs.
Upvotes: 3