public abstract class ByteToMessageDecoder extends 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 extendsByteToMessageDecoder
{@Override
public void decode(ChannelHandlerContext
ctx,ByteBuf
in, List<Object> out) throwsException
{ out.add(in.readBytes(in.readableBytes())); } }
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.
Be aware that sub-classes of ByteToMessageDecoder
MUST NOT
annotated with @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.
限定符和类型 | 类和说明 |
---|---|
static interface |
ByteToMessageDecoder.Cumulator
Cumulate
ByteBuf s. |
ChannelHandler.Sharable
限定符和类型 | 字段和说明 |
---|---|
static ByteToMessageDecoder.Cumulator |
COMPOSITE_CUMULATOR
Cumulate
ByteBuf s by add them to a CompositeByteBuf and so do no memory copy whenever possible. |
static ByteToMessageDecoder.Cumulator |
MERGE_CUMULATOR
|
限定符 | 构造器和说明 |
---|---|
protected |
ByteToMessageDecoder() |
限定符和类型 | 方法和说明 |
---|---|
protected int |
actualReadableBytes()
Returns the actual number of readable bytes in the internal cumulative
buffer of this decoder.
|
protected void |
callDecode(ChannelHandlerContext ctx,
ByteBuf in,
java.util.List<java.lang.Object> out)
Called once data should be decoded from the given
ByteBuf . |
void |
channelInactive(ChannelHandlerContext ctx)
Calls
ChannelHandlerContext.fireChannelInactive() to forward
to the next ChannelInboundHandler in the ChannelPipeline . |
void |
channelRead(ChannelHandlerContext ctx,
java.lang.Object msg)
Calls
ChannelHandlerContext.fireChannelRead(Object) to forward
to the next ChannelInboundHandler in the ChannelPipeline . |
void |
channelReadComplete(ChannelHandlerContext ctx)
Calls
ChannelHandlerContext.fireChannelReadComplete() to forward
to the next ChannelInboundHandler in the ChannelPipeline . |
protected abstract void |
decode(ChannelHandlerContext ctx,
ByteBuf in,
java.util.List<java.lang.Object> out)
Decode the from one
ByteBuf to an other. |
protected void |
decodeLast(ChannelHandlerContext ctx,
ByteBuf in,
java.util.List<java.lang.Object> out)
Is called one last time when the
ChannelHandlerContext goes in-active. |
protected void |
discardSomeReadBytes() |
void |
handlerRemoved(ChannelHandlerContext ctx)
Do nothing by default, sub-classes may override this method.
|
protected void |
handlerRemoved0(ChannelHandlerContext ctx)
Gets called after the
ByteToMessageDecoder was removed from the actual context and it doesn't handle
events anymore. |
protected ByteBuf |
internalBuffer()
Returns the internal cumulative buffer of this decoder.
|
boolean |
isSingleDecode()
If
true then only one message is decoded on each
channelRead(ChannelHandlerContext, Object) call. |
void |
setCumulator(ByteToMessageDecoder.Cumulator cumulator)
Set the
ByteToMessageDecoder.Cumulator to use for cumulate the received ByteBuf s. |
void |
setDiscardAfterReads(int discardAfterReads)
Set the number of reads after which
ByteBuf.discardSomeReadBytes() are called and so free up memory. |
void |
setSingleDecode(boolean singleDecode)
If set then only one message is decoded on each
channelRead(ChannelHandlerContext, Object)
call. |
void |
userEventTriggered(ChannelHandlerContext ctx,
java.lang.Object evt)
Calls
ChannelHandlerContext.fireUserEventTriggered(Object) to forward
to the next ChannelInboundHandler in the ChannelPipeline . |
channelActive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught
ensureNotSharable, handlerAdded, isSharable
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
handlerAdded
public static final ByteToMessageDecoder.Cumulator MERGE_CUMULATOR
public static final ByteToMessageDecoder.Cumulator COMPOSITE_CUMULATOR
ByteBuf
s by add them to a CompositeByteBuf
and so do no memory copy whenever possible.
Be aware that CompositeByteBuf
use a more complex indexing implementation so depending on your use-case
and the decoder implementation this may be slower than just use the MERGE_CUMULATOR
.public void setSingleDecode(boolean singleDecode)
channelRead(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 is false
as this has performance impacts.public boolean isSingleDecode()
true
then only one message is decoded on each
channelRead(ChannelHandlerContext, Object)
call.
Default is false
as this has performance impacts.public void setCumulator(ByteToMessageDecoder.Cumulator cumulator)
ByteToMessageDecoder.Cumulator
to use for cumulate the received ByteBuf
s.public void setDiscardAfterReads(int discardAfterReads)
ByteBuf.discardSomeReadBytes()
are called and so free up memory.
The default is 16
.protected int actualReadableBytes()
internalBuffer().readableBytes()
.protected ByteBuf internalBuffer()
public final void handlerRemoved(ChannelHandlerContext ctx) throws java.lang.Exception
ChannelHandlerAdapter
handlerRemoved
在接口中 ChannelHandler
handlerRemoved
在类中 ChannelHandlerAdapter
java.lang.Exception
protected void handlerRemoved0(ChannelHandlerContext ctx) throws java.lang.Exception
ByteToMessageDecoder
was removed from the actual context and it doesn't handle
events anymore.java.lang.Exception
public void channelRead(ChannelHandlerContext ctx, java.lang.Object msg) throws java.lang.Exception
ChannelInboundHandlerAdapter
ChannelHandlerContext.fireChannelRead(Object)
to forward
to the next ChannelInboundHandler
in the ChannelPipeline
.
Sub-classes may override this method to change behavior.channelRead
在接口中 ChannelInboundHandler
channelRead
在类中 ChannelInboundHandlerAdapter
java.lang.Exception
public void channelReadComplete(ChannelHandlerContext ctx) throws java.lang.Exception
ChannelInboundHandlerAdapter
ChannelHandlerContext.fireChannelReadComplete()
to forward
to the next ChannelInboundHandler
in the ChannelPipeline
.
Sub-classes may override this method to change behavior.channelReadComplete
在接口中 ChannelInboundHandler
channelReadComplete
在类中 ChannelInboundHandlerAdapter
java.lang.Exception
protected final void discardSomeReadBytes()
public void channelInactive(ChannelHandlerContext ctx) throws java.lang.Exception
ChannelInboundHandlerAdapter
ChannelHandlerContext.fireChannelInactive()
to forward
to the next ChannelInboundHandler
in the ChannelPipeline
.
Sub-classes may override this method to change behavior.channelInactive
在接口中 ChannelInboundHandler
channelInactive
在类中 ChannelInboundHandlerAdapter
java.lang.Exception
public void userEventTriggered(ChannelHandlerContext ctx, java.lang.Object evt) throws java.lang.Exception
ChannelInboundHandlerAdapter
ChannelHandlerContext.fireUserEventTriggered(Object)
to forward
to the next ChannelInboundHandler
in the ChannelPipeline
.
Sub-classes may override this method to change behavior.userEventTriggered
在接口中 ChannelInboundHandler
userEventTriggered
在类中 ChannelInboundHandlerAdapter
java.lang.Exception
protected void callDecode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out)
ByteBuf
. This method will call
decode(ChannelHandlerContext, ByteBuf, List)
as long as decoding should take place.ctx
- the ChannelHandlerContext
which this ByteToMessageDecoder
belongs toin
- the ByteBuf
from which to read dataout
- the List
to which decoded messages should be addedprotected abstract void decode(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out) throws java.lang.Exception
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
.ctx
- the ChannelHandlerContext
which this ByteToMessageDecoder
belongs toin
- the ByteBuf
from which to read dataout
- the List
to which decoded messages should be addedjava.lang.Exception
- is thrown if an error occursprotected void decodeLast(ChannelHandlerContext ctx, ByteBuf in, java.util.List<java.lang.Object> out) throws java.lang.Exception
ChannelHandlerContext
goes in-active. Which means the
channelInactive(ChannelHandlerContext)
was triggered.
By default, this will just call decode(ChannelHandlerContext, ByteBuf, List)
but sub-classes may
override this for some special cleanup operation.java.lang.Exception