Class ByteToMessageDecoder
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.servicetalk.transport.netty.internal.ByteToMessageDecoder
-
- All Implemented Interfaces:
io.netty.channel.ChannelHandler,io.netty.channel.ChannelInboundHandler
public abstract class ByteToMessageDecoder extends io.netty.channel.ChannelInboundHandlerAdapterChannelInboundHandlerAdapterwhich 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 callingin.getInt(0)is assuming the frame starts at the beginning of the buffer, which is not always the case. Usein.getInt(in.readerIndex())instead.Pitfalls
Be aware that sub-classes of
ByteToMessageDecoderMUST NOT annotated withChannelHandler.Sharable.Some methods such as
ByteBuf.readBytes(int)will cause a memory leak if the returned buffer is not released or added to theoutList. Use derived buffers likeByteBuf.readSlice(int)to avoid leaking memory.
-
-
Constructor Summary
Constructors Modifier Constructor Description protectedByteToMessageDecoder(io.netty.buffer.ByteBufAllocator cumulationAllocator)Create a new instance.
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description voidchannelInactive(io.netty.channel.ChannelHandlerContext ctx)voidchannelRead(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg)voidchannelReadComplete(io.netty.channel.ChannelHandlerContext ctx)protected voidcumulationReset()Resets cumulation.protected abstract voiddecode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in)Decode the from oneByteBufto an other.protected voiddecodeLast(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in)Is called one last time when theChannelHandlerContextgoes in-active.voidhandlerRemoved(io.netty.channel.ChannelHandlerContext ctx)protected voidhandlerRemoved0(io.netty.channel.ChannelHandlerContext ctx)Gets called after theByteToMessageDecoderwas removed from the actual context and it doesn't handle events anymore.protected io.netty.buffer.ByteBufswapAndCopyCumulation(io.netty.buffer.ByteBuf cumulation, io.netty.buffer.ByteBuf in)Swap the existingcumulationByteBuffor a newByteBufand copyin.voiduserEventTriggered(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object evt)-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, isSharable
-
-
-
-
Constructor Detail
-
ByteToMessageDecoder
protected ByteToMessageDecoder(io.netty.buffer.ByteBufAllocator cumulationAllocator)
Create a new instance.- Parameters:
cumulationAllocator- UnpooledByteBufAllocatorused to allocate more memory, if necessary for cumulation.- Throws:
java.lang.IllegalArgumentException- if the providedcumulationAllocatoris not unpooled.
-
-
Method Detail
-
handlerRemoved
public final void handlerRemoved(io.netty.channel.ChannelHandlerContext ctx)
- Specified by:
handlerRemovedin interfaceio.netty.channel.ChannelHandler- Overrides:
handlerRemovedin classio.netty.channel.ChannelHandlerAdapter
-
handlerRemoved0
protected void handlerRemoved0(io.netty.channel.ChannelHandlerContext ctx)
Gets called after theByteToMessageDecoderwas removed from the actual context and it doesn't handle events anymore.- Parameters:
ctx- theChannelHandlerContextwhich thisByteToMessageDecoderbelongs to
-
channelRead
public void channelRead(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg)- Specified by:
channelReadin interfaceio.netty.channel.ChannelInboundHandler- Overrides:
channelReadin classio.netty.channel.ChannelInboundHandlerAdapter
-
channelReadComplete
public void channelReadComplete(io.netty.channel.ChannelHandlerContext ctx)
- Specified by:
channelReadCompletein interfaceio.netty.channel.ChannelInboundHandler- Overrides:
channelReadCompletein classio.netty.channel.ChannelInboundHandlerAdapter
-
swapAndCopyCumulation
protected io.netty.buffer.ByteBuf swapAndCopyCumulation(io.netty.buffer.ByteBuf cumulation, io.netty.buffer.ByteBuf in)Swap the existingcumulationByteBuffor a newByteBufand copyin. This method is called when a heuristic determines the amount of unused bytes is sufficiently high that a resize / defragmentation of the bytes fromcumulationis beneficial.ByteBuf.discardReadBytes()is generally avoided in this method because it changes the underlying data structure. If others have slices of thisByteBuftheir view on the data will become corrupted. This is commonly a problem when processing data asynchronously to avoid blocking theEventLoopthread.- Parameters:
cumulation- TheByteBufthat accumulates across socket read operations.in- The bytes to copy.- Returns:
- the result of the swap and copy operation.
-
cumulationReset
protected void cumulationReset()
Resets cumulation.
-
channelInactive
public void channelInactive(io.netty.channel.ChannelHandlerContext ctx)
- Specified by:
channelInactivein interfaceio.netty.channel.ChannelInboundHandler- Overrides:
channelInactivein classio.netty.channel.ChannelInboundHandlerAdapter
-
userEventTriggered
public void userEventTriggered(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object evt) throws java.lang.Exception- Specified by:
userEventTriggeredin interfaceio.netty.channel.ChannelInboundHandler- Overrides:
userEventTriggeredin classio.netty.channel.ChannelInboundHandlerAdapter- Throws:
java.lang.Exception
-
decode
protected abstract void decode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in) throws java.lang.ExceptionDecode 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 data- Throws:
java.lang.Exception- is thrown if an error occurs
-
decodeLast
protected void decodeLast(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in) throws java.lang.ExceptionIs called one last time when theChannelHandlerContextgoes in-active. Which means thechannelInactive(ChannelHandlerContext)was triggered. By default this will just calldecode(ChannelHandlerContext, ByteBuf)but sub-classes may override this for some special cleanup operation.- Parameters:
ctx- theChannelHandlerContextwhich thisByteToMessageDecoderbelongs toin- theByteBuffrom which to read data- Throws:
java.lang.Exception- is thrown if an error occurs
-
-