Netty学习笔记12——编解码器框架
来源:互联网 发布:淘宝买书有什么好店铺 编辑:程序博客网 时间:2024/06/06 02:03
文本内容来自《Netty实战》学习笔记
一、解码器
1.把字节解码为消息
1) ByteToMessageDecoder
方法:
decode(ChannelHandlerContext ctx,ByteBuf in,List<Object> out)必须实现的抽象方法。调用时传入一个ByteBuf,以及一个用来添加解码消息的List。对这个方法的调用将会重复进行,直到确定没有新的元素被添加到该List,或者该ByteBuf中没有更多可读取的字节时为止。然后,如果该List不为空,那么它的内容将会被传递人ChannelPipeline中的下一个ChannelInboundHandler。decodeLast(ChannelHandlerContext ctx,ByteBuf in,List<Object> out)Netty提供的这个默认实现只是简单 调用了decode()方法。当Channel的状态变为非活动时,这个方法将会被调用一次。可以重写该方法以提供特殊的处理。
示例:每次从入站ByteBuf读取4个字节,将其解码为一个int,然后将它添加到一个List中。当没有更多的元素中以被添加到该List中时,它的内容将会发送给下一个Channel-InboundHandler。
public class ToIntegerDecoder extends ByteToMessageDecoder{ @Override public void decode(ChannelHandlerContext ctx,ByteBuf in, List<Object> out) throws Exception{ if (in.readableBytes() >= 4){ out.add(in.readInt()); } }}
原来类型 int被添加到List中时,会被自动装箱为Integer。
一旦消息被编码或者解码,它就会被ReferenceCountUtil.release(message)调用自动释放。如果需要保留引用以便稍后使用,那么可以调用ReferenceCountUtil.retain(message)方法,它会将增加引用计数,从而防止该消息被释放。
2)ReplayingDecoder
ReplayingDecoder扩展了ByteToMessageDecoder类,使我们不必调用readableBytes()方法。它通过使用一个自定义的ByteBuf实现ReplayingDecodeerByteBuf包装传入的ByteBuf实现了这一点,其将在内部执行该调用。
该类的完整声明:
public abstract class ReplayingDecoder<S> extends ByteToMessageDecoder
类型参数S指定了用于状态管理的类型,其中Void代表不需要状态管理。
仍然实现上述案例:
public class ToIntegerDecoder2 extends ReplayingDecoder<Void>{ @Override public void decode (ChannelHandlerContext ctx,ByteBuf in,List<Object> out) throws Exception{ out.add(in.readInt()); }}
在读取readInt时,如果没有足够的字节可用,可抛出一个Error。其将在基类里捕获并处理。
注意点:
- 不是所有的ByteBuf操作都被支持。如果调用了一个不被支持的方法,将会抛出一个UnsupportedOperationException
- ReplayingDecoder 稍慢于ByteToMessageDecoder
其它的解码器
- io.netty.handler.codec.LineBasedFrameDecoder 使用了行尾控制字符来解析消息数据
- io.netty.handler.codec.http.HttpObjectDecoder HTTP数据的解码器。
2.将一种消息类型解码为另一种
MessageToMessageDecoder
用来在两个消息格式之间转换。
decode(ChannelHandlerContext ctx,I msg,List<Object> out)对于每个需要被解码为另一种格式的入站消息来说,该方法都将会被调用。解码消息随后会被传递人ChannelPipeline中的下一个ChannelInboundHandler。
下面示例是IntegerToStringDecoder的实现。
public class IntegerToStringDecoder extends MessageToDecoder<Integer>{ @Override public void decode(ChannelHandlerContext ctx,Integer msg , List<Object> out) throws Exception{ out.add(String.valueOf(msg)); }}
3. 解码器在帧超出指定的大小限制时抛出异常
TooLongFrameException类
public class SafeByteToMessageDecoder extends ByteToMessageDecoder{ private static final int MAX_FRAME_SIZE = 1024; @Override public void decode(ChannelHandlerContext ctx,ByteBuf in,List<Object> out) throws Exception{ int readable = in.radableBytes(); if(readable > MAX_FRAME_SIZE){ in.skipBytes(readable); throw new TooLongFrameException("Frame too big!"); } }}
二、编码器
编码器实现了ChannelOutboundHandler,将出站数据从一种格式转换为另一种格式。类似的,有:
MesageToByteEncoder
MessageToMessageEncoder
CombinedChannelDuplexHandler类
其声明为:
public class CombinedChannelDuplexHandler,<I extends ChannelInboundHandler, o extends ChannelOutboundHandler>
这个类充当了ChannelInboundHandler和ChannelOutboundHandler的容器。
这个类我觉得不用也没关系,以后用到时再详细看看。
这前几篇文章介绍了几个内置编解码器。
Netty权威指南 第2版学习笔记4——TCP粘包/拆包问题的解决之道
Netty权威指南 第2版学习笔记5——分隔符和定长解码器的应用
Netty权威指南 第2版学习笔记6——常见序列化与反序列化框架
Netty权威指南 第2版学习笔记7——MessagePack编解码及LengthFieldBasedFrameDecoder
- Netty学习笔记12——编解码器框架
- netty编解码器
- Netty学习笔记—helloWorld
- Netty学习笔记—IO模型
- netty的编解码器介绍
- netty的编解码器介绍
- 编解码器框架
- Netty权威指南 第2版学习笔记6——常见序列化与反序列化框架
- 【Netty】netty学习笔记一
- Netty权威指南 第2版学习笔记3——Netty NIO开发指南
- Netty实战学习笔记(一)——Netty的概念及体系结构
- netty学习笔记(一)—结合reactor模式探索netty对网络io的处理机制
- netty学习笔记(一)—结合reactor模式探索netty对网络io的处理机制
- Netty学习笔记13——一些问题记录处理
- Netty源码学习笔记
- Netty学习笔记一
- Netty 学习笔记
- Netty学习笔记
- centos下mysql配置
- Unity后处理实现物体外描边
- nginx 部署angular项目
- NFS服务器不能挂载问题终极解决办法
- 发送定长宝解决网络粘包问题
- Netty学习笔记12——编解码器框架
- could not be set to a 'string' value. You must set this property to a non-null value of type
- Oracle中connect,resource角色权限
- 判断一个节点是否在一棵二叉树中&&判断一颗二叉树是是否是另一颗树的子树
- 设备管理器
- Js中的深拷贝与浅拷贝
- NYOJ-746整数划分(四)
- 偶串
- Java 生成word模板