Class ByteToMessageDecoder
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.netty.handler.codec.ByteToMessageDecoder
-
- All Implemented Interfaces:
ChannelHandler,ChannelInboundHandler
- Direct Known Subclasses:
AbstractMemcacheObjectDecoder,BrotliDecoder,Bzip2Decoder,CleartextHttp2ServerUpgradeHandler,DelimiterBasedFrameDecoder,FastLzFrameDecoder,FixedLengthFrameDecoder,HAProxyMessageDecoder,Http2ConnectionHandler,HttpObjectDecoder,JsonObjectDecoder,LengthFieldBasedFrameDecoder,LineBasedFrameDecoder,Lz4FrameDecoder,LzfDecoder,OptionalSslHandler,ProtobufVarint32FrameDecoder,RedisDecoder,ReplayingDecoder,SnappyFrameDecoder,Socks5PrivateAuthRequestDecoder,Socks5PrivateAuthResponseDecoder,SocksPortUnificationServerHandler,SpdyFrameCodec,SslClientHelloHandler,SslHandler,WebSocket08FrameDecoder,XmlDecoder,XmlFrameDecoder,ZlibDecoder,ZstdDecoder
public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapterwhich decodes bytes in a stream-like fashion from oneByteBufto an other Message type. For example here is an implementation which reads all readable bytes from the inputByteBufand create a newByteBuf.public class SquareDecoder extendsByteToMessageDecoder{@Overridepublic void decode(ChannelHandlerContextctx,ByteBufin, List<Object> out) throwsException{ out.add(in.readBytes(in.readableBytes())); } }Frame detection
Generally frame detection should be handled earlier in the pipeline by adding a
DelimiterBasedFrameDecoder,FixedLengthFrameDecoder,LengthFieldBasedFrameDecoder, orLineBasedFrameDecoder.If a custom frame decoder is required, then one needs to be careful when implementing one with
ByteToMessageDecoder. Ensure there are enough bytes in the buffer for a complete frame by checkingByteBuf.readableBytes(). If there are not enough bytes for a complete frame, return without modifying the reader index to allow more bytes to arrive.To check for complete frames without modifying the reader index, use methods like
ByteBuf.getInt(int). One MUST use the reader index when using methods likeByteBuf.getInt(int). For example calling in.getInt(0) is assuming the frame starts at the beginning of the buffer, which is not always the case. Use in.getInt(in.readerIndex()) instead.Pitfalls
Be aware that sub-classes of
ByteToMessageDecoderMUST NOT annotated with {@link @Sharable}.Some methods such as
ByteBuf.readBytes(int)will cause a memory leak if the returned buffer is not released or added to the outList. Use derived buffers likeByteBuf.readSlice(int)to avoid leaking memory.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceByteToMessageDecoder.CumulatorCumulateByteBufs.-
Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
ChannelHandler.Sharable
-
-
Field Summary
Fields Modifier and Type Field Description static ByteToMessageDecoder.CumulatorCOMPOSITE_CUMULATORCumulateByteBufs by add them to aCompositeByteBufand so do no memory copy whenever possible.static ByteToMessageDecoder.CumulatorMERGE_CUMULATOR
-
Constructor Summary
Constructors Modifier Constructor Description protectedByteToMessageDecoder()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected intactualReadableBytes()Returns the actual number of readable bytes in the internal cumulative buffer of this decoder.protected voidcallDecode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)Called once data should be decoded from the givenByteBuf.voidchannelInactive(ChannelHandlerContext ctx)CallsChannelHandlerContext.fireChannelInactive()to forward to the nextChannelInboundHandlerin theChannelPipeline.voidchannelRead(ChannelHandlerContext ctx, java.lang.Object msg)CallsChannelHandlerContext.fireChannelRead(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline.voidchannelReadComplete(ChannelHandlerContext ctx)CallsChannelHandlerContext.fireChannelReadComplete()to forward to the nextChannelInboundHandlerin theChannelPipeline.protected abstract voiddecode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)Decode the from oneByteBufto an other.protected voiddecodeLast(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)Is called one last time when theChannelHandlerContextgoes in-active.protected voiddiscardSomeReadBytes()voidhandlerRemoved(ChannelHandlerContext ctx)Do nothing by default, sub-classes may override this method.protected voidhandlerRemoved0(ChannelHandlerContext ctx)Gets called after theByteToMessageDecoderwas removed from the actual context and it doesn't handle events anymore.protected ByteBufinternalBuffer()Returns the internal cumulative buffer of this decoder.booleanisSingleDecode()Iftruethen only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)call.voidsetCumulator(ByteToMessageDecoder.Cumulator cumulator)Set theByteToMessageDecoder.Cumulatorto use for cumulate the receivedByteBufs.voidsetDiscardAfterReads(int discardAfterReads)Set the number of reads after whichByteBuf.discardSomeReadBytes()are called and so free up memory.voidsetSingleDecode(boolean singleDecode)If set then only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)call.voiduserEventTriggered(ChannelHandlerContext ctx, java.lang.Object evt)CallsChannelHandlerContext.fireUserEventTriggered(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline.-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, isSharable
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.netty.channel.ChannelHandler
handlerAdded
-
-
-
-
Field Detail
-
MERGE_CUMULATOR
public static final ByteToMessageDecoder.Cumulator MERGE_CUMULATOR
-
COMPOSITE_CUMULATOR
public static final ByteToMessageDecoder.Cumulator COMPOSITE_CUMULATOR
CumulateByteBufs by add them to aCompositeByteBufand so do no memory copy whenever possible. Be aware thatCompositeByteBufuse a more complex indexing implementation so depending on your use-case and the decoder implementation this may be slower than just use theMERGE_CUMULATOR.
-
-
Method Detail
-
setSingleDecode
public void setSingleDecode(boolean singleDecode)
If set then only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)call. This may be useful if you need to do some protocol upgrade and want to make sure nothing is mixed up. Default isfalseas this has performance impacts.
-
isSingleDecode
public boolean isSingleDecode()
Iftruethen only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)call. Default isfalseas this has performance impacts.
-
setCumulator
public void setCumulator(ByteToMessageDecoder.Cumulator cumulator)
Set theByteToMessageDecoder.Cumulatorto use for cumulate the receivedByteBufs.
-
setDiscardAfterReads
public void setDiscardAfterReads(int discardAfterReads)
Set the number of reads after whichByteBuf.discardSomeReadBytes()are called and so free up memory. The default is16.
-
actualReadableBytes
protected int actualReadableBytes()
Returns the actual number of readable bytes in the internal cumulative buffer of this decoder. You usually do not need to rely on this value to write a decoder. Use it only when you must use it at your own risk. This method is a shortcut tointernalBuffer().readableBytes().
-
internalBuffer
protected ByteBuf internalBuffer()
Returns the internal cumulative buffer of this decoder. You usually do not need to access the internal buffer directly to write a decoder. Use it only when you must use it at your own risk.
-
handlerRemoved
public final void handlerRemoved(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelHandlerAdapterDo nothing by default, sub-classes may override this method.- Specified by:
handlerRemovedin interfaceChannelHandler- Overrides:
handlerRemovedin classChannelHandlerAdapter- Throws:
java.lang.Exception
-
handlerRemoved0
protected void handlerRemoved0(ChannelHandlerContext ctx) throws java.lang.Exception
Gets called after theByteToMessageDecoderwas removed from the actual context and it doesn't handle events anymore.- Throws:
java.lang.Exception
-
channelRead
public void channelRead(ChannelHandlerContext ctx, java.lang.Object msg) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelRead(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelReadin interfaceChannelInboundHandler- Overrides:
channelReadin classChannelInboundHandlerAdapter- Throws:
java.lang.Exception
-
channelReadComplete
public void channelReadComplete(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelReadComplete()to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelReadCompletein interfaceChannelInboundHandler- Overrides:
channelReadCompletein classChannelInboundHandlerAdapter- Throws:
java.lang.Exception
-
discardSomeReadBytes
protected final void discardSomeReadBytes()
-
channelInactive
public void channelInactive(ChannelHandlerContext ctx) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelInactive()to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelInactivein interfaceChannelInboundHandler- Overrides:
channelInactivein classChannelInboundHandlerAdapter- Throws:
java.lang.Exception
-
userEventTriggered
public void userEventTriggered(ChannelHandlerContext ctx, java.lang.Object evt) throws java.lang.Exception
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireUserEventTriggered(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
userEventTriggeredin interfaceChannelInboundHandler- Overrides:
userEventTriggeredin classChannelInboundHandlerAdapter- Throws:
java.lang.Exception
-
callDecode
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)
Called once data should be decoded from the givenByteBuf. This method will calldecode(ChannelHandlerContext, ByteBuf, List)as long as decoding should take place.- Parameters:
ctx- theChannelHandlerContextwhich thisByteToMessageDecoderbelongs toin- theByteBuffrom which to read dataout- theListto which decoded messages should be added
-
decode
protected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out) throws java.lang.Exception
Decode the from oneByteBufto an other. This method will be called till either the inputByteBufhas nothing to read when return from this method or till nothing was read from the inputByteBuf.- Parameters:
ctx- theChannelHandlerContextwhich thisByteToMessageDecoderbelongs toin- theByteBuffrom which to read dataout- theListto which decoded messages should be added- Throws:
java.lang.Exception- is thrown if an error occurs
-
decodeLast
protected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out) throws java.lang.Exception
Is called one last time when theChannelHandlerContextgoes in-active. Which means thechannelInactive(ChannelHandlerContext)was triggered. By default, this will just calldecode(ChannelHandlerContext, ByteBuf, List)but sub-classes may override this for some special cleanup operation.- Throws:
java.lang.Exception
-
-