解码器
将字节解码为消息:ByteToMessageDecoder和ReplayingDecoder
将一种消息解码成另一种消息:MessageToMessageDecoder
每当需要为ChannelPipeline中的下一个ChannelInboundHandle转换入站数据时会用到。
抽象类ByteToMessageDecoder
Decode(ChannelHandlerContext ctx, ByteBuf in, List out): 方法被调用时将会传入一个包含了传入数据的 ByteBuf ,以及一个用来添加解码消息的 List 。对这个方法的调用将会重复进行,直到确定没有新的元素被添加到该 List ,或者该 ByteBuf 中没有更多可读取的字节时为止。然后,如果该 List 不为空,那么它的内容将会被传递给ChannelPipeline 中的下一个 ChannelInboundHandler。
public class ToIntegerDecoder extends ByteToMessageDecoder {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (in.readableBytes() >= 4) {
out.add(in.readInt());
}
}
}
抽象类ReplayingDecoder
ReplayingDecoder扩展了ByteToMessageDecoder类,使得我们不必调用readableBytes()方法。
public class ToIntegerDecoder2 extends ReplayingDecoder<Void> {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
out.add(in.readInt());
}
}
- 并不是所有的 ByteBuf 操作都被支持,如果调用了一个不被支持的方法,将会抛出一个UnsupportedOperationException;
- ReplayingDecoder 稍慢于 ByteToMessageDecoder。
抽象类MessageToMessageDecoder
从一种pojo类型转换成另一种。
decode(ChannelHandlerContext ctx, I msg, List out) : 对于每个需要被解码为另一种格式的入站消息来说,该方法都将会被调用。解码消息随后会被传递给 ChannelPipeline中的下一个 ChannelInboundHandler。
public class IntegerToStringDecoder extendsMessageToMessageDecoder<Integer> {
@Override
public void decode(ChannelHandlerContext ctx, Integer msg,List<Object> out) throws Exception {
out.add(String.valueOf(msg));
}
}
编码器
抽象类 MessageToByteEncoder
encode(ChannelHandlerContext ctx, I msg, ByteBuf out) 是你需要实现的唯一抽象方法。它被调用时将会传入要被该类编码为 ByteBuf 的(类型为 I 的)出站消息。该 ByteBuf 随后将会被转发给 ChannelPipeline中的下一个 ChannelOutboundHandler。
public class ShortToByteEncoder extends MessageToByteEncoder<Short> {
@Override
public void encode(ChannelHandlerContext ctx, Short msg, ByteBuf out)throws Exception {
out.writeShort(msg);
}
}
抽象类 MessageToMessageEncoder
encode(ChannelHandlerContext ctx, I msg, List out):每个通过 write() 方法写入的消息都将会被传递给 encode() 方法,以编码为一个或者多个出站消息。随后,这些出站消息将会被转发给 ChannelPipeline中的下一个 ChannelOutboundHandler。
public class IntegerToStringEncoder
extends MessageToMessageEncoder<Integer> {
@Override
public void encode(ChannelHandlerContext ctx, Integer msg,List<Object> out) throws Exception {
out.add(String.valueOf(msg));
}
}
抽象的编解码器类
抽象类ByteToMessageCodec
在一些场景下,我们需要将字节解码成某种形式的消息,可能是pojo,随后再次对它进行解码。
方法 | 描述 |
---|---|
decode(ChannelHandlerContext ctx, ByteBuf in, List) | 只要有字节可以被消费,这个方法就将会被调用。它将入站ByteBuf 转 换 为 指 定 的 消 息 格 式 , 并 将 其 转 发 给ChannelPipeline 中的下一个 ChannelInboundHandler。 |
DecodeLast(ChannelHandlerContext ctx, ByteBuf in, List) | 这个方法的默认实现委托给了 decode() 方法。它只会在Channel 的状态变为非活动时被调用一次。它可以被重写以实现特殊的处理。 |
encode(ChannelHandlerContext ctx, I msg, ByteBuf out) | 对于每个将被编码并写入出站 ByteBuf 的(类型为 I 的)消息来说,这个方法都将会被调用。 |
抽象类 MessageToMessageCodec
方法 | 描述 |
---|---|
decode(ChannelHandlerContext ctx,INBOUND_IN msg,List out) | 这个方法被调用时会被传入 INBOUND_IN 类型的消息。它将把它们解码为 OUTBOUND_IN 类型的消息,这些消息将被转发给 ChannelPipeline 中的下一个 ChannelInboundHandler。 |
encode(ChannelHandlerContext ctx, OUTBOUND_IN msg, List out) | 对于每个 OUTBOUND_IN 类型的消息,这个方法都将会被调用。这些消息将会被编码为 INBOUND_IN 类型的消息,然后被转发给 ChannelPipeline 中的下一个ChannelOutboundHandler。 |
decode()方法是将INBOUND_IN类型的消息转换为OUTBOUND_IN类型的消息,而encode()方法则进行它的逆向操作。将INBOUND_IN类型的消息看作是通过网络发送的类型,而将OUTBOUND_IN类型的消息看作是应用程序所处理的类型。