Netty4:源码解析ObjectDecoder和ObjectEncoder两个类
Posted 你是小KS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Netty4:源码解析ObjectDecoder和ObjectEncoder两个类相关的知识,希望对你有一定的参考价值。
1.声明
当前内容主要用于本人学习和了解netty中的ObjectDecoder和ObjectEncoder这两个类,明白其主要原理和主要操作
原因:之前使用ObjectDecoder传递对象的时候出现了一个问题,无法传递消息,无法接收消息,碰到了坑,所以要了解!
2.ObjectDecoder源码解析
直接找到解码方法
@Override
protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception
ByteBuf frame = (ByteBuf) super.decode(ctx, in);
if (frame == null)
return null;
ObjectInputStream ois = new CompactObjectInputStream(new ByteBufInputStream(frame, true), classResolver);
try
return ois.readObject();
finally
ois.close();
发现主要实现:基于ByteBuf实现,通过解析流为对象流方式得到解码后的Object
采用调试方式查看:
这里明白了,为什么不能调用ReferenceCountUtil.release(msg);
,之前有过这个错误!
继续:
结果得到一个标准的序列化对象输入流,解析为对象的(这就是为什么需要实现序列化接口的要求!)
最后就是标准的readObject方法
3.ObjectEncoder源码解析
直接查看加码方法
@Override
protected void encode(ChannelHandlerContext ctx, Serializable msg, ByteBuf out) throws Exception
int startIdx = out.writerIndex();
ByteBufOutputStream bout = new ByteBufOutputStream(out);
ObjectOutputStream oout = null;
try
bout.write(LENGTH_PLACEHOLDER);
oout = new CompactObjectOutputStream(bout);
oout.writeObject(msg);
oout.flush();
finally
if (oout != null)
oout.close();
else
bout.close();
int endIdx = out.writerIndex();
out.setInt(startIdx, endIdx - startIdx - 4);
发现传递的为实现序列化的msg,并且采用ObjectOutputStream直接写出对象到ByteBuf中,(所以传输的对象必须实现序列化接口,其中会自动释放掉ByteBuf(父类中实现了
))
4.总结
1.使用ObjectDecoder和ObjectEncoder不要手动释放msg
,并且传递的对象都是需要实现序列化接口的
,否则任何一点出现问题,那么程序就会出现无法接收消息和无法传递消息的问题!
以上是关于Netty4:源码解析ObjectDecoder和ObjectEncoder两个类的主要内容,如果未能解决你的问题,请参考以下文章
《Elasticsearch 源码解析与优化实战》第15章:Transport模块分析
Netty4.xNetty源码分析之LineBasedFrameDecoder