Skip to content

JdkZlibDecoder 与 JdkZlibEncoder 问题 #2

@codebuks

Description

@codebuks

购买了您掘金和慕课网的课程,很优质的内容,很棒,非常感谢。
最近在做一个项目,使用到了zlib压缩,大致的流程是这样:

编解码规则

  • 测试报文

78 9c ca 48 cd c9 c9 d7 51 c8 4b 2d 29 a9 54 04 00 00 00 ff ff eb 90 eb 90 eb 90

  • 编码规则

字符串 -> zlib压缩 -> 添加包尾 -> 发送

  • 解码规则相反

读取一帧 -> 去包尾 -> zlib解压 -> 字符串

其中包尾定义为EB 90 EB 90 EB 90

  • 代码片段
protected void initChannel(NioSocketChannel ch) {
    log.info("init channel !");
     // 处理读数据的逻辑链
    ByteBuf delimiter = Unpooled.copiedBuffer(Constants.TAIL);
     ch.pipeline().addLast(new DelimiterBasedFrameDecoder(2048, delimiter));
    ch.pipeline().addLast(new JdkZlibDecoder());
    ch.pipeline().addLast(new StringDecoder());
    ch.pipeline().addLast(new InBoundHandler());
                        
    // 写逻辑处理
    ch.pipeline().addLast(new DelimiterEncoder());
    ch.pipeline().addLast(new JdkZlibEncoder());
    ch.pipeline().addLast(new StringEncoder());                        
}

调试中,我发现io.netty.handler.codec.compression包下的JdkZlibDecoderJdkZlibEncoder都有一个finish标记,这就导致我只能编解码一次,不清楚为何这样设计,最后我只能用了笨办法:

@Slf4j
public class InBoundHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        log.info("MyInBoundHandler: " + msg);
        ctx.pipeline().replace(JdkZlibDecoder.class, "zlibDecoder", new JdkZlibDecoder());
        String content = "hello, netty!";
        ctx.channel().writeAndFlush(content);
    }

}
@Slf4j
public class DelimiterEncoder extends MessageToByteEncoder<ByteBuf> {
    

    @Override
    protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
        log.info("writeBytes");
        System.err.println(ByteBufUtil.prettyHexDump(msg));
        out.writeBytes(msg);
        out.writeBytes(Constants.TAIL);
        ctx.pipeline().replace(JdkZlibEncoder.class, "zlibEncoder", new JdkZlibEncoder());
    }


}

我的问题是:

  1. netty这样设计的目的?
  2. 像我这样使用有没有问题?
  3. 如果需要连续使用,除了自定义编解码器,和我上面用的办法,有没有别的办法?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions