Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • JAVA基础

  • 集合容器

  • Netty

    • IO模型
    • Netty初级
      • 1、通用API
      • 2、解码器
      • 3、DefaultChannelGroup
      • 4、半包粘包
      • 5、Netty字节缓冲区对象ByteBuf
      • 6、ChannelInboundHandlerAdapter
      • 7、protostuff
      • 8、文件传输
      • 9、ReferenceCountUtil.release()
      • 10、Netty同步请求处理
    • Netty原理
  • JVM

  • JUC

  • Java
  • Netty
phan
2023-05-15
目录

Netty初级

# Netty初级

# 1、通用API

channelActive:客户端链接后触发该函数

channelRead:客户端向服务端往通道缓存发送数据后触发该函数。服务端调用该api取数据。

writeAndFlush:发送ByteBuf字节码数据给客户端

# 2、解码器

解码器:服务端将接收到的字节码转换为String字符串

LineBasedFrameDecoder:换行解码器,碰到换行符号才会调用触发channelRead方法

StringDecoder:用于服务端接收数据解码转String,需要设置GBK。

StringEncoder:用于服务端向客户端发送数据,自动将String转化成字节码

# 3、DefaultChannelGroup

DefaultChannelGroup:服务端设置信道组,每次有客户端发来请求后将其放入通信组中,可以直接对通信组实现群发。

flush()方法,刷新内存队列,将数据写入到对端。

# 4、半包粘包

半包数据:客户端发送的一包数据到服务端,接收时拆分成多包

粘包数据:收到的数据包中结束符号标志后面还带有其它的数据。

因此需要在服务端自定义编码解码器来处理以上问题。

# 5、Netty字节缓冲区对象ByteBuf

readByte():读取缓冲区当前读指针位置的内容,然后readerIndex指针+1

readerIndex():获取当前数据包的开头读位置Index

readerIndex(num):将读指针位置置为num

# 6、ChannelInboundHandlerAdapter

ChannelInboundHandlerAdapter:拦截处理入站事件,对于服务端来说,包括客户端连接、读客户端发送过来的数据、断开连接。用户在自定义处理方法时需要重写事件方法

channelRead:信道缓冲区收到数据后,进行读数据。

channelActive:服务端监听到客户端连接,信道激活。

channelInactive:服务端监听到客户端断开连接。

Bootstrap#option:ChannelOption.AUTO_READ自动读模式

# 7、protostuff

基于protostuff传输对象数据。需要自己定义解码器和编码器,并在其中调用框架API实现字节码和对象之间的序列化和反序列化。

# 8、文件传输

底层通过java的RandomAccessFile类实现对文件的读写操作。客户端和服务端之间文件传输通过FileTransferProtocol自定义协议实现。

FileUtil#readFile:把客户端要上传的文件读到缓存中

FileUtil#writeFile:服务端把缓存中的数据写入最终指定位置,并返回客户端下次读取指针,

FileBurstData:文件数据。

FileBurstInstruct:文件传输指令。由服务端发给客户端,客户端把文件数据传过来写入通道缓冲区。

FileDescInfo:文件传输请求。用于初次请求,相当于建立连接。

①客户端向通道缓冲区发送FileDescInfo对象,请求进行文件传输

②服务端收到后,判断是FileDescInfo类型,首先读Cache查看是否有该文件的传输指令(有则表明客户端可能刚刚断开过链接),有则直接返回该对象,否则创建新的FileBurstInstruct对象返回写入缓冲区。

③客户端根据FileBurstInstruct对象从文件指定位置读取数据,并封装为FileBurstData对象发给服务端,写入通道缓冲区。

④服务端收到后,判断是FileBurstInstruct类型,则会把真正的文件数据通过java原生API写入指定的文件位置(服务端指定)。并在FileBurstInstruct中更新下一次客户端的文件读指针,并放入Cache。

# 9、ReferenceCountUtil.release()

ReferenceCountUtil.release():相当于ByteBuf.release()方法的包装,释放缓冲区资源。

netty4中的ByteBuf使用了引用计数(netty4实现了一个可选的ByteBuf池),每一个新分配的ByteBuf的引用计数值为1,每对这个ByteBuf对象增加一个引用,需要调用ByteBuf.retain()方法,而每减少一个引用,需要调用ByteBuf.release()方法。当这个ByteBuf对象的引用计数值为0时,表示此对象可回收。

# 10、Netty同步请求处理

Netty使用了事件通知机制(channelRead),因此它的IO是异步的。而要实现Netty同步请求,这里的方案是通过countDownlatch和future配合实现,当前客户端线程通过writeAndFlush发送消息后,使用countdownlatch将该线程阻塞,然后服务端响应回复后唤醒客户端线程,通过future.get()获取响应数据。整个流程如下:

①客户端通过writeAndFlush向缓冲区发送请求数据,并添加监听器,确保客户端发送成功。

然后客户端在writeFuture.get中线程阻塞,等待服务端响应数据,从而实现同步。(基于latch.await实现)此处给latch设置了超时时间,没有完全阻塞,超时后计数还没有为0则返回false。

②服务端通过channelRead收到请求数据,并将响应结果发送给客户端。

③客户端在channelRead中收到响应数据后,从Future缓存中取出对应的future对象,将响应数据封装进去,并countDown()唤醒前面的请求线程。

编辑 (opens new window)
#Netty
上次更新: 2023/12/15, 15:49:57
IO模型
Netty原理

← IO模型 Netty原理→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式