- java.lang.Object
-
- io.netty5.channel.ChannelHandlerAdapter
-
- io.netty5.handler.codec.ByteToMessageDecoder
-
- All Implemented Interfaces:
ChannelHandler
- Direct Known Subclasses:
CleartextHttp2ServerUpgradeHandler
,DecompressionHandler
,DelimiterBasedFrameDecoder
,FixedLengthFrameDecoder
,Http2ConnectionHandler
,HttpObjectDecoder
,LengthFieldBasedFrameDecoder
,LineBasedFrameDecoder
,OptionalSslHandler
,SslClientHelloHandler
,SslHandler
,WebSocket13FrameDecoder
public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter
ChannelHandler
which decodes bytes in a stream-like fashion from oneBuffer
to an other Message type. For example here is an implementation which reads all readable bytes from the inputBuffer
, creates a newBuffer
and forward it to the nextChannelHandler
in theChannelPipeline
.public class SquareDecoder extends
ByteToMessageDecoder
{@Override
public void decode(ChannelHandlerContext
ctx,Buffer
in) throwsException
{ ctx.fireChannelRead(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 checkingBuffer.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
BufferAccessor.getInt(int)
. One MUST use the reader index when using methods likeBufferAccessor.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 {@link @Sharable}.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
ByteToMessageDecoder.Cumulator
CumulateBuffer
s.
-
Field Summary
Fields Modifier and Type Field Description static ByteToMessageDecoder.Cumulator
COMPOSITE_CUMULATOR
CumulateBuffer
s by add them to aCompositeBuffer
and so do no memory copy whenever possible.static ByteToMessageDecoder.Cumulator
MERGE_CUMULATOR
-
Constructor Summary
Constructors Modifier Constructor Description protected
ByteToMessageDecoder()
protected
ByteToMessageDecoder(ByteToMessageDecoder.Cumulator cumulator)
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected int
actualReadableBytes()
Returns the actual number of readable bytes in the internal cumulative buffer of this decoder.void
channelInactive(ChannelHandlerContext ctx)
TheChannel
of theChannelHandlerContext
was registered is now inactive and reached its end of lifetime.void
channelRead(ChannelHandlerContext ctx, Object msg)
Invoked when the currentChannel
has read a message from the peer.void
channelReadComplete(ChannelHandlerContext ctx)
Invoked when the last message read by the current read operation has been consumed byChannelHandler.channelRead(ChannelHandlerContext, Object)
.void
channelShutdown(ChannelHandlerContext ctx, ChannelShutdownDirection direction)
TheChannel
of theChannelHandlerContext
was shutdown in one direction.protected abstract void
decode(ChannelHandlerContext ctx, Buffer in)
Decode the from oneBuffer
to another.protected void
decodeLast(ChannelHandlerContext ctx, Buffer in)
Is called one last time when theChannelHandlerContext
goes in-active.protected void
discardSomeReadBytes()
void
handlerAdded(ChannelHandlerContext ctx)
Gets called after theChannelHandler
was added to the actual context and it's ready to handle events.protected void
handlerAdded0(ChannelHandlerContext ctx)
void
handlerRemoved(ChannelHandlerContext ctx)
Gets called after theChannelHandler
was removed from the actual context and it doesn't handle events anymore.protected void
handlerRemoved0(ChannelHandlerContext ctx)
Gets called after theByteToMessageDecoder
was removed from the actual context and it doesn't handle events anymore.protected Buffer
internalBuffer()
Returns the internal cumulative buffer of this decoder, if exists, elsenull
.boolean
isSharable()
Returnstrue
if this handler is sharable and thus can be added to more than oneChannelPipeline
.boolean
isSingleDecode()
Iftrue
then only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)
call.void
setSingleDecode(boolean singleDecode)
If set then only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)
call.-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.netty5.channel.ChannelHandler
bind, channelActive, channelExceptionCaught, channelInboundEvent, channelRegistered, channelUnregistered, channelWritabilityChanged, close, connect, deregister, disconnect, flush, pendingOutboundBytes, read, register, sendOutboundEvent, shutdown, write
-
-
-
-
Field Detail
-
MERGE_CUMULATOR
public static final ByteToMessageDecoder.Cumulator MERGE_CUMULATOR
-
COMPOSITE_CUMULATOR
public static final ByteToMessageDecoder.Cumulator COMPOSITE_CUMULATOR
CumulateBuffer
s by add them to aCompositeBuffer
and so do no memory copy whenever possible. Be aware thatCompositeBuffer
use a more complex indexing implementation so depending on your use-case and the decoder implementation this may be slower than just use theMERGE_CUMULATOR
.
-
-
Constructor Detail
-
ByteToMessageDecoder
protected ByteToMessageDecoder()
-
ByteToMessageDecoder
protected ByteToMessageDecoder(ByteToMessageDecoder.Cumulator cumulator)
-
-
Method Detail
-
isSharable
public final boolean isSharable()
Description copied from interface:ChannelHandler
Returnstrue
if this handler is sharable and thus can be added to more than oneChannelPipeline
. By default, this method returnsfalse
. If this method returnsfalse
, you have to create a new handler instance every time you add it to a pipeline because it has unshared state such as member variables.
-
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 isfalse
as this has performance impacts.
-
isSingleDecode
public boolean isSingleDecode()
Iftrue
then only one message is decoded on eachchannelRead(ChannelHandlerContext, Object)
call. Default isfalse
as this has performance impacts.
-
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 Buffer internalBuffer()
Returns the internal cumulative buffer of this decoder, if exists, elsenull
. 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.- Returns:
- Internal
Buffer
if exists, elsenull
.
-
handlerAdded
public final void handlerAdded(ChannelHandlerContext ctx) throws Exception
Description copied from interface:ChannelHandler
Gets called after theChannelHandler
was added to the actual context and it's ready to handle events.- Throws:
Exception
-
handlerAdded0
protected void handlerAdded0(ChannelHandlerContext ctx) throws Exception
- Throws:
Exception
-
handlerRemoved
public final void handlerRemoved(ChannelHandlerContext ctx) throws Exception
Description copied from interface:ChannelHandler
Gets called after theChannelHandler
was removed from the actual context and it doesn't handle events anymore.- Throws:
Exception
-
handlerRemoved0
protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception
Gets called after theByteToMessageDecoder
was removed from the actual context and it doesn't handle events anymore.- Throws:
Exception
-
channelRead
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
Description copied from interface:ChannelHandler
Invoked when the currentChannel
has read a message from the peer.- Throws:
Exception
-
channelReadComplete
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception
Description copied from interface:ChannelHandler
Invoked when the last message read by the current read operation has been consumed byChannelHandler.channelRead(ChannelHandlerContext, Object)
. IfChannelOption.AUTO_READ
is off, no further attempt to read an inbound data from the currentChannel
will be made untilChannelHandlerContext.read()
is called.- Throws:
Exception
-
discardSomeReadBytes
protected final void discardSomeReadBytes()
-
channelInactive
public void channelInactive(ChannelHandlerContext ctx) throws Exception
Description copied from interface:ChannelHandler
TheChannel
of theChannelHandlerContext
was registered is now inactive and reached its end of lifetime.- Throws:
Exception
-
channelShutdown
public void channelShutdown(ChannelHandlerContext ctx, ChannelShutdownDirection direction) throws Exception
Description copied from interface:ChannelHandler
TheChannel
of theChannelHandlerContext
was shutdown in one direction. This might either be because the remote peer did cause a shutdown of one direction or the shutdown was requested explicit by us and was executed.- Parameters:
ctx
- theChannelHandlerContext
for which we notify about the completed shutdown.direction
- theChannelShutdownDirection
of the completed shutdown.- Throws:
Exception
-
decode
protected abstract void decode(ChannelHandlerContext ctx, Buffer in) throws Exception
Decode the from oneBuffer
to another. This method will be called till either the inputBuffer
has nothing to read when return from this method or till nothing was read from the inputBuffer
.- Parameters:
ctx
- theChannelHandlerContext
which thisByteToMessageDecoder
belongs toin
- theBuffer
from which to read data- Throws:
Exception
- is thrown if an error occurs
-
decodeLast
protected void decodeLast(ChannelHandlerContext ctx, Buffer in) throws Exception
Is called one last time when theChannelHandlerContext
goes in-active. Which means thechannelInactive(ChannelHandlerContext)
was triggered. By default this will just calldecode(ChannelHandlerContext, Buffer)
but sub-classes may override this for some special cleanup operation.- Throws:
Exception
-
-