Netty - 编解码器框架

解码器

将字节解码为消息 - ByteToMessageDecoder和ReplayingDecoder

将一种消息类型转为另一种 - MessageToMessageDecoder

netty中的解码器继承了ChannelInboundHandlerAdapter,提供了为Pipeline中的下一个ChannelInBoundHandler转换入站数据的作用

ByteToMessageDecoder

实现从ByteBuf中读取Int并传递到下一个ChannleHandler中

public class ToIntegerDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception {
        if(byteBuf.isReadable()) {
            list.add(byteBuf.readInt());
        }
    }
}

ReplayingDecoder

该类拓展了ByteToMessageDecoder,不必调用readableBytes方法,通过一个自定义的ByteBuf实现-ReplayingDecoderByteBuf,包装传入的ByteBuf实现了这一点,其将在内部执行时候调用

public int readInt() {
    this.checkReadableBytes(4);
    return this.buffer.readInt();
}

实现一个IntToStringDecoder

public class ToIntegerDecoder2 extends ReplayingDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception {
        list.add(byteBuf.readInt());
    }
}

ReplayingDecoderByteBuf并不支持所有的ByteBuf操作,如果调用了一个不被支持的方法,会抛出UnsupportOperationException,并且该类执行稍慢于ByteToMessageDecoder

MessageToMessageDecoder

实现了两种不同消息格式之间的互转,实现一个IntegerToStringMessageDecoder

public class IntegerToStringMessageDecoder extends MessageToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, Integer integer, List list) throws Exception {
        list.add(String.valueOf(integer));
    }
}

TooLongFrameException

netty是一个异步框架,需要在字节可以解码之前缓存他们,但是不能让解码器大量缓冲数据以至于耗尽内存,neety提供了TooLongFrameException类,将由解码器在帧超出指定的限制大小时抛出

public class SafeByteToMessageDecoder extends ByteToMessageDecoder {
    
    private final int MAX_SIZE = 1024;
    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception {
        int bytes = byteBuf.readableBytes();
        if(bytes > MAX_SIZE) {
            byteBuf.skipBytes(bytes);
            throw new TooLongFrameException("2 long");
        }
    }
}

编码器

MessageToByteEncoder

public class StringToBytesEncoder extends MessageToByteEncoder {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, String s, ByteBuf byteBuf) throws Exception {
        byteBuf.writeBytes(s.getBytes());
    }
}

MessageToMessageEncoder

public class IntegerToStringEncoder extends MessageToMessageEncoder {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Integer integer, List list) throws Exception {
        list.add(String.valueOf(integer));
    }
}

编解码器

MessageToMessageCodec

使用该类,可以在一个单个类中实现转换的往返过程

public class MsgToMsgCodec extends MessageToMessageCodec {
    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, String s, List list) throws Exception {
        list.add(Integer.parseInt(s));
    }

    @Override
    protected void decode(ChannelHandlerContext channelHandlerContext, Integer integer, List list) throws Exception {
        list.add(String.valueOf(integer));
    }
}

CombinedChannelDuplexHandler

结合编解码器可能会对可重用性造成影响,所以netty提供了CombinedChannelDuplexHandler类,该类充当了Inbound和outBound的容器

@ChannelHandler.Sharable
public class CombinedStringIntegerCodec extends CombinedChannelDuplexHandler {
    
    public CombinedStringIntegerCodec() {
        super(new IntegerToStringMessageDecoder(),new IntegerToStringEncoder());
    }
}

该方式相比于使用编解码器更加灵活,也取决于个人编程习惯

你可能感兴趣的:(Netty - 编解码器框架)