-
Notifications
You must be signed in to change notification settings - Fork 598
Open
Description
购买了您掘金和慕课网的课程,很优质的内容,很棒,非常感谢。
最近在做一个项目,使用到了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包下的JdkZlibDecoder和JdkZlibEncoder都有一个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());
}
}我的问题是:
- netty这样设计的目的?
- 像我这样使用有没有问题?
- 如果需要连续使用,除了自定义编解码器,和我上面用的办法,有没有别的办法?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels