Netty-编码器----学习孙哥&不良人课程

148 阅读4分钟

编解码器 (Codec)

1. 什么是编解码
1. 编码  Java对象 ---》 二进制 (Byte)  转换成Byte  才能通过网络进行传输
2. 解码  二进制   ---》 Java对象        转换成Java对象

广义编解码 (codec) 2部分
1. encode  Java对象 ---》 二进制 (Byte)
2. decode  二进制   ---》 Java对象 

image-20221106191651404

image-20231103105802130

image-20231103105848705

Netty中编解码的体现 
1. 
   1. encode  Java对象 ---》 二进制 (Byte)
   2. decode  二进制   ---》 Java对象 
   
2. Netty中编解码工作 谁做的呢?
   Handler --> ChannelHandler 
   
   ByteToMessageCodec 
   一种编解码器,用于动态编码将字节解码为消息,反之亦然。这可以看作是 ByteToMessageDecoder 和 MessageToByteEncoder 的组合。请注意,ByteToMessageCodec 的子类不得使用 @Sharable 进行批注。
   ByteToMessageDecoder  --- 实际开发解码器 就作为这个类型的子类 
   MessageToByteEncoder  --- 实际开发编码器 就作为这个类型的子类 
  
3. 编解码器 在使用过程中 2部分核心内容
   1. 序列化协议(编码格式)(传输数据的格式)
      1. java序列化 和 反序列化 
         1. 类 implements Seriliazable接口 (标识性接口)接口里面没有方法 实现的 Spring ThrowsAdvice
         2. ObjectOutputStream ---> Java 转换成 二进制的内容 ---> 文件|通过网络进行传输 
            ObjectInputStream  ---> 二进制的内容 转换成 Java 
         3. serialVersionUID private static final long 
            1. serialVersionUID --> 如果不显示创建 java在序列化的过程中会不会创建?默认创建的 hashCode 
            
         
         问题:
            1. 无法跨语言的
            2. 可读性差 ---> 二进制
            3. java序列化后的数据大小 大 ---》 ByteBuffer 5倍 传输效率 低
            4. java序列化操作的时间 ---》ByteBuffer 5倍
   
      2. XML
            c   --------------------------------------------  s
            <user>
               <id>1</id>
               <name>sunshuai</name>
            </user>
            
      3. JSON
           可读性好 {"name":"sunshuai","age":10},数据量 > 二进制的内容。 HTTP协议 + JSON ->SpringCloud
           
      4. msgpack
          类似于JSON,二进制传输。效率高 数据体量小 ---》支持多语言的  【bson ---> mongodb】4倍与protobuf
          
      5. protobuf google
         二进制 支持多种编程语言 -> 自己的编译器,把数据格式编译成中间语言 ---> go python.. 更小 更快 可读性差。
         Hadoop  
       
   2. 具体的编解码器 
       ByteToMessageDecoder  --- 实际开发解码器 就作为这个类型的子类 
       MessageToByteEncoder  --- 实际开发编码器 就作为这个类型的子类 
Netty常见的编解码器
1. StringDecoder StringEncoder
功能 --- String转换 
注意:
   Netty的编解码体系中 
   1. ByteToMessage
      MessageToByte
      
      MessageToMessageDecoder
      MessageToMessageEncoder
      
   2. 区别
      1. Byte系列的编解码 更底层
         decode方法参数 观察到的
         
      2. ByteToMessage体系 
         解决封帧的问题 (半包 粘包)
         
         MessageToMessage不自己解决。
         FixedLengthFrameDecoder
         LineBasedFrameDecoder 
         LengthFieldBasedFrameDecoder
         
2. 封帧相关的
   FixedLengthFrameDecoder
   LineBasedFrameDecoder 
   LengthFieldBasedFrameDecoder
   
3. Java序列化相关的编解码
    ObjectEncoder  
    
    ObjectDecoder()  LengthFieldBasedFrameDecoder子类 不会有半包粘包
    
    编解码器 Netty。做了一定的优化,数据小 ---> 幻术 


4. JSON相关的编解码器
   Netty JSON编码器(String ---> ) 只提供了JSON解码器 JsonObjectDecoder
   针对于JSON数据 做封帧的(半包 粘包)
   
5. Http协议编解码操作 
   Netty支持对Http协议进行编解码 ---》 Netty可以作为Web服务器 ---》 SpringWebFlex 底层就是基于Netty. --->Gateway
   
   1. HttpServerCodec()
   2. HttpObject子类进行编程了。
   
   
   1. pipeline的调用与 Message的个数相关
   2. 可以通过SimpleChannelInboundHandler<T>限定消息的类型
   3. channelRead0 和 channelRead区别是什么?
      channelRead底层调用channelRead0
      在channelRead中已经对于msg做了类型的转换。
   4. HttpObjectAggregator  作用:
      HttpRequest 和 HttpContent 聚合在一起。
      
   5. Http协议的解码器,会出现半包粘包问题么?
      Http协议Content-Length ---> 数据 不会出现。

image-20221108195020505转存失败,建议直接上传图片文件

自定义编解码器
1. 编码器  
   extends MessageToByteEncoder
   encode
 
2. 编码器
   extends ByteToMessageDecoder
   1. 如果ByteBuf的数据一次解码没有处理完成,则Netty会重复调用decode方法
   
3. extends ByteToMessageCodec
   编解码器 合二为一
   
4. Netty提供的一个特殊的解码器 ReplayingDecoder
   他的实现类 中的decode方法 不需要做任何安全设置。
    if(in.readableBytes()>=8){
            long reciveLong= in.readLong();
            out.add(reciveLong);
        }
        可以不需要做校验,但我们这种校验并不安全,可能读的8个字节不是long 错位
        或者中途抛出异常,我们要回滚读指针
        如果使用了ReplayingDecoder就可以不做安全校验
        
   
   Netty编程 
     1. Bytebuf读写指针 
     2. Bytebuf释放