Class ByteToMessageDecoder

  • All Implemented Interfaces:
    io.netty.channel.ChannelHandler, io.netty.channel.ChannelInboundHandler

    public abstract class ByteToMessageDecoder
    extends io.netty.channel.ChannelInboundHandlerAdapter
    ChannelInboundHandlerAdapter which decodes bytes in a stream-like fashion from one ByteBuf to an other Message type. For example here is an implementation which reads all readable bytes from the input ByteBuf and create a new ByteBuf.
         public class SquareDecoder extends ByteToMessageDecoder {
             @Override
             public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
                     throws Exception {
                 out.add(in.readBytes(in.readableBytes()));
             }
         }
     

    Frame detection

    Generally frame detection should be handled earlier in the pipeline by adding a DelimiterBasedFrameDecoder, FixedLengthFrameDecoder, LengthFieldBasedFrameDecoder, or LineBasedFrameDecoder.

    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 checking ByteBuf.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 like ByteBuf.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 ByteToMessageDecoder MUST NOT annotated with ChannelHandler.Sharable.

    Some methods such as ByteBuf.readBytes(int) will cause a memory leak if the returned buffer is not released or added to the out List. Use derived buffers like ByteBuf.readSlice(int) to avoid leaking memory.

    • Nested Class Summary

      • Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler

        io.netty.channel.ChannelHandler.Sharable
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected ByteToMessageDecoder​(io.netty.buffer.ByteBufAllocator cumulationAllocator)
      Create a new instance.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      void channelInactive​(io.netty.channel.ChannelHandlerContext ctx)  
      void channelRead​(io.netty.channel.ChannelHandlerContext ctx, java.lang.Object msg)  
      void channelReadComplete​(io.netty.channel.ChannelHandlerContext ctx)  
      protected void cumulationReset()
      Resets cumulation.
      protected abstract void decode​(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in)
      Decode the from one ByteBuf to an other.
      protected void decodeLast​(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in)
      Is called one last time when the ChannelHandlerContext goes in-active.
      void handlerRemoved​(io.netty.channel.ChannelHandlerContext ctx)  
      protected void handlerRemoved0​(io.netty.channel.ChannelHandlerContext ctx)
      Gets called after the ByteToMessageDecoder was removed from the actual context and it doesn't handle events anymore.
      protected io.netty.buffer.ByteBuf swapAndCopyCumulation​(io.netty.buffer.ByteBuf cumulation, io.netty.buffer.ByteBuf in)
      Swap the existing cumulation ByteBuf for a new ByteBuf and copy in.
      void userEventTriggered​(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
      • 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
    • Constructor Detail

      • ByteToMessageDecoder

        protected ByteToMessageDecoder​(io.netty.buffer.ByteBufAllocator cumulationAllocator)
        Create a new instance.
        Parameters:
        cumulationAllocator - Unpooled ByteBufAllocator used to allocate more memory, if necessary for cumulation.
        Throws:
        java.lang.IllegalArgumentException - if the provided cumulationAllocator is not unpooled.
    • Method Detail

      • handlerRemoved

        public final void handlerRemoved​(io.netty.channel.ChannelHandlerContext ctx)
        Specified by:
        handlerRemoved in interface io.netty.channel.ChannelHandler
        Overrides:
        handlerRemoved in class io.netty.channel.ChannelHandlerAdapter
      • handlerRemoved0

        protected void handlerRemoved0​(io.netty.channel.ChannelHandlerContext ctx)
        Gets called after the ByteToMessageDecoder was removed from the actual context and it doesn't handle events anymore.
        Parameters:
        ctx - the ChannelHandlerContext which this ByteToMessageDecoder belongs to
      • channelRead

        public void channelRead​(io.netty.channel.ChannelHandlerContext ctx,
                                java.lang.Object msg)
        Specified by:
        channelRead in interface io.netty.channel.ChannelInboundHandler
        Overrides:
        channelRead in class io.netty.channel.ChannelInboundHandlerAdapter
      • channelReadComplete

        public void channelReadComplete​(io.netty.channel.ChannelHandlerContext ctx)
        Specified by:
        channelReadComplete in interface io.netty.channel.ChannelInboundHandler
        Overrides:
        channelReadComplete in class io.netty.channel.ChannelInboundHandlerAdapter
      • swapAndCopyCumulation

        protected io.netty.buffer.ByteBuf swapAndCopyCumulation​(io.netty.buffer.ByteBuf cumulation,
                                                                io.netty.buffer.ByteBuf in)
        Swap the existing cumulation ByteBuf for a new ByteBuf and copy in. This method is called when a heuristic determines the amount of unused bytes is sufficiently high that a resize / defragmentation of the bytes from cumulation is beneficial.

        ByteBuf.discardReadBytes() is generally avoided in this method because it changes the underlying data structure. If others have slices of this ByteBuf their view on the data will become corrupted. This is commonly a problem when processing data asynchronously to avoid blocking the EventLoop thread.

        Parameters:
        cumulation - The ByteBuf that 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:
        channelInactive in interface io.netty.channel.ChannelInboundHandler
        Overrides:
        channelInactive in class io.netty.channel.ChannelInboundHandlerAdapter
      • userEventTriggered

        public void userEventTriggered​(io.netty.channel.ChannelHandlerContext ctx,
                                       java.lang.Object evt)
                                throws java.lang.Exception
        Specified by:
        userEventTriggered in interface io.netty.channel.ChannelInboundHandler
        Overrides:
        userEventTriggered in class io.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.Exception
        Decode the from one ByteBuf to an other. This method will be called till either the input ByteBuf has nothing to read when return from this method or till nothing was read from the input ByteBuf.
        Parameters:
        ctx - the ChannelHandlerContext which this ByteToMessageDecoder belongs to
        in - the ByteBuf from 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.Exception
        Is called one last time when the ChannelHandlerContext goes in-active. Which means the channelInactive(ChannelHandlerContext) was triggered. By default this will just call decode(ChannelHandlerContext, ByteBuf) but sub-classes may override this for some special cleanup operation.
        Parameters:
        ctx - the ChannelHandlerContext which this ByteToMessageDecoder belongs to
        in - the ByteBuf from which to read data
        Throws:
        java.lang.Exception - is thrown if an error occurs