一、io.netty.util.IllegalReferenceCountException: refCnt: 0
从字面意思看是不合法的计数引用异常,我们知道Netty中ByteBuf资源释放是靠引用计数的,类似JVM垃圾回收的引用计数,当资源被引用时,计数器+1,调用release或其他方式申请释放资源,计数器-1,计数器为0时ByteBuf释放掉。由此,我们需要结合自己代码看哪里资源释放出了问题。我的代码写法如下
public class MyServerInHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
super.channelRead(ctx, msg);
ByteBuf byteBuf = (ByteBuf) msg;
String requeString = byteBuf.toString(CharsetUtil.UTF_8);
System.out.println("服务端收到的内容为" + requeString);
ctx.writeAndFlush(Unpooled.copiedBuffer("hello " + requeString, CharsetUtil.UTF_8));
}
}
在服务器Hander中我调用了父类的ChannelRead方法,去掉之后就可以了。为啥呢?因为父类ChannelRead方法如下
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.fireChannelRead(msg);
}
ChannelHandlerContext .fireChannelRead方法会把资源在PipeLine中传递,PipeLine一头一尾两个Handler会专门释放资源,资源都释放了还怎么读取,害。所以继承时不要随便调用父类方法,父类方法达不到要求我们才扩展的,要自行判断是完全覆盖还是部分功能扩展。
二、继承ChannelInBondHandler,重写的channelRead0(ChannelHandlerContext ctx, ByteBuf msg)没有执行
该方法在每次消息有完整接收后都会调用,如果自己定义了消息终止符号或者使用系统定义的换行符作为消息结束符,都会被调用,除非接收方PipeLine中添加了消息结束的ChannelInBondHander,发送发缺没有在消息末尾添加消息结束符。(仅列举除了自己遇到的场景,当然还有其他可能,不一一列举)
三、客户端解析FullHttpResponse报文内容失败,不报错,控制台打印了CompositeByteBuf(ridx: 0, widx: 201, cap: 201, components=1),客户端未设置编码,使用resp.content().toString(CharsetUtil.UTF_8)即可。
四、服务端向客户端发送响应,客户端未收到响应。在向客户端写应加上如下代码,ctx.write(response).addListener(ChannelFutureListener.CLOSE);原因不清楚,客户端发送请求不需要这样写。
五、Netty集成MessagePack时报错,org.msgpack.MessageTypeException: Cannot find template for class com.jyf.netty.msgpack.User class. Try to add @Message annotation to the class or call MessagePack.register(Type).在需要序列化的类加上标签@Message