在看了FrameDecoder后,我们接下来再看ReplayingDecoder,我们首先分析下为什么我们已经有了功能非常强大的FrameDecoder了,还行ReplayingDecoder呢,就从下面的例子看起。
假设消息结构是这样的:
VERSION - 1 byte TYPE - 1 byte PAYLOAD_LENGTH - 4 bytes PAYLOAD - N bytes (depends on the value read at PAYLOAD_LENGTH)
如果我们用FrameDecoder来实现的的话,我们可能要反复读多次这个帧才能被解析出来,然后程序写起来也是比较麻烦的,而且性能也比较低下。
我们再来看一下消息结构体:
public class Envelope { private Version version; private Type type; private byte[] payload; public Envelope() { } public Envelope(Version version, Type type, byte[] payload) { this.version = version; this.type = type; this.payload = payload; } // getters & setters }我们再来看一下消息编码:
public class Encoder extends OneToOneEncoder { // ... public static ChannelBuffer encodeMessage(Envelope message) throws IllegalArgumentException { // verify that no fields are set to null // version(1b) + type(1b) + payload length(4b) + payload(nb) int size = 6 + message.getPayload().length; ChannelBuffer buffer = ChannelBuffers.buffer(size); buffer.writeByte(message.getVersion().getByteValue()); buffer.writeByte(message.getType().getByteValue()); buffer.writeInt(message.getPayload().length); buffer.writeBytes(message.getPayload()); return buffer; } @Override protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object msg) throws Exception { if (msg instanceof Envelope) { return encodeMessage((Envelope) msg); } else { return msg; } } // ..这个里面比较重要的是要定义一下解码的状态:
public enum DecodingState { VERSION, TYPE, PAYLOAD_LENGTH, PAYLOAD, }我们再来看一下编码的实现:
@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, DecodingState state) throws Exception { switch (state) { case VERSION: this.message.setVersion(Version.fromByte(buffer.readByte())); checkpoint(DecodingState.TYPE); case TYPE: this.message.setType(Type.fromByte(buffer.readByte())); checkpoint(DecodingState.PAYLOAD_LENGTH); case PAYLOAD_LENGTH: int size = buffer.readInt(); if (size <= 0) { throw new Exception("Invalid content size"); } byte[] content = new byte[size]; this.message.setPayload(content); checkpoint(DecodingState.PAYLOAD); case PAYLOAD: buffer.readBytes(this.message.getPayload(), 0, this.message.getPayload().length); try { return this.message; } finally { this.reset(); } default: throw new Exception("Unknown decoding state: " + state); } } private void reset() { checkpoint(DecodingState.VERSION); this.message = new Envelope(); }这个里面的switch语句我们要特别注意一下,这个里面的checkpoint是当失败后下一次解码的执行点。 不多解释了,这个还是比较好理解的,基本上展现了这个解码器的用法。
相关推荐
一个netty的入门教程以及源码分析视频,适合刚学习的人
netty源码解析PDF,网络编程
美团基础架构部闪电侠老师的netty源码分析视频
共分两大章:第1 章:深入浅出Netty源码剖析,第2 章:NIO+Netty5各种RPC架构实战演练,以及课程资料,希望对象学习netty的童靴有用。
Netty源码分析总结.rar
netty源码
netty基本使用以及入门资料,具有netty的源码的分析以及服务器启动过程的介绍
netty源码和相关中文文档。帮助您快速上手netty开发。netty体验之旅祝您愉快
netty源码解析视频教程,深入浅出netty源码视频
Netty好资料,Buffer介绍
Netty源码剖析+视频
Netty5.0架构剖析和源码解读.pdf是一本比较全的讲解netty5的书籍,任何对java的nio技术感兴趣的人都值得一看。
【项目实战】Netty源码剖析&NIO;+Netty5各种RPC架构实战演练三部曲视频教程(未加密)
Netty权威指南源码
Netty源码解读之线程
netty-3.3.1.Final-sources.jar src源码
视频分两部分 第1 章 : 第一部分、深入浅出Netty源码剖析。。 第2 章 : 第二部分、NIO+Netty5各种RPC架构实战演练
netty源码包,可以本地搭建netty源码环境,学习nio模式
netty 源码
Netty源码依赖包,最新版源码依赖包,源码解读必备