INDEX
Bootstrap & ServerBootstrap
作用
- 用于引导 Netty 应用
- 可以对 Netty 进行配置
Bootstrap
用于引导客户端,ServerBootstrap
用于引导服务端
常用方法
配置 EventLoop
group()
- 服务端需要配置两个,通常叫做 boss、workers
- 客户端只需要配置一个
配置服务端通道实现类
channel()
为 ServerChannel
添加配置
option()
为接受到的通道添加配置
childOption()
为 boss 配置业务处理类
handler()
为 worker 配置业务处理类
childHandler()
服务端绑定端口
bind()
客户端连接服务器
connect()
Channel
作用
- Netty 网络通讯的组件,用于网络 IO 操作
- 支持关联的 IO 的操作,以及与之对应的处理逻辑
- 可以获取相关信息,如状态、配置等
- 异步调用的,会立即返回
ChannelFuture
- 实现丰富,以应对不同协议、不同阻塞类型
NioSocketChannel
:异步,客户端,TCPNioServerSocketChannel
:异步,服务端,TCPNioDatagramChannel
:异步,UDPNioSctpChannel
:异步,客户端,SCTPNioSctpServerChannel
:异步,服务端,SCTP
常用方法
获取 Pipeline
Pipeline()
获取配置
config()
获取访问地址
remoteAddress()
写出并刷新
writeAndFlush()
Future & ChannelFuture
作用
- 用于异步监听操作的执行结果
- 可以配合 FutureListener 机制使用
常用方法
返回通道
channel()
等待异步操作执行完成
sync()
注意这个方法是同步的
它是同步的等待,但被等待的是个异步操作
添加监听器
addListener()
Selector
作用
- Netty 网络通讯的组件,用于实现多路复用,做到一个线程监管多个
Channel
- 集成在
EnentLoop
中,其上级对象叫 chooser - 可以对
EnentLoop
中的通道进行轮询,并在其就绪时选中
更多信息参考 基础 | NIO - [Selector]
ChannelHandler
作用
- Netty 网络通讯的组件
- 可以处理 IO 事件
- 也可以拦截 IO 事件,并将 IO 事件转发给
Pipeline
的下一个 handler
- 多个
ChannelHandler
可以协同处理业务 - 很类似过滤器
- 本身是个接口,提供丰富的待实现方法
- 接口分出两个分支
ChannelInboundHandler
:负载处理进站 IO 事件
用于处理 从对方流向自己 的 IO 事件,比如作为客户端接受服务端响应ChannelInboundHandler
:负载处理出站 IO 事件
用于处理 从自己流向对方 的 IO 事件,比如作为客户端向服务端发请求- 其实还有个
ChannelDuplexHandler
,但使用场景很少 (违反单一职责违反的太明显了)
- 接口和两个分支接口,各自有一个配置模式实现
- 对应类图如下
- 接口分出两个分支
常用方法
激活时回调
channelActive()
取消激活时回调
channelInactive()
读取时回调
channelRead()
读取完成时回调
channelReadComplete()
写出时回调
channelWrite()
写出完成时回调
channelWriteComplete()
异常时回调
exceptionCaught()
handler 加入时回调
handlerAdded()
hander 已经加入了对应的 context 并可以真正处理事件时触发
- 相当于一个
Channel
注册到Selector
并完成准备工作时触发 - 相当于一个新连接建立完全后触发
handler 移除时回调
handlerRemoved()
Pipeline & ChannelPipeline
作用
- 作为 Handler 的集合,负责处理、拦截出入站 IO 事件
- 很类似过滤器栈,责任链模式
- 可以完全控制 IO 事件的处理方式,并控制各个
ChannelHandler
如何相互调用
结构
- 每个
Channel
都有且仅有一个Pipeline
二者关系参考 并发编程 | Netty - [Reactor 模型] ChannelPipeline
本质上是一个双向链表- 链表的节点类型是
ChannelHandlerContext
,ChannelHandlerContext
内部是ChannelHandler
- 通常不同
Pipeline
中的ChannelHandler
不共享
技术上是可以做到共享的,但是一旦共享就需要处理线程安全问题,影响性能 - 入站、出站的
ChannelHandler
在同一个链表中,但不会互相影响,Handler 与当前操作不符时会直接放行
常用方法
头部追加 Handler
addFirst()
尾部追加 Handler
addLast()
ChannelHandlerContext
作用
- 是
Pipeline
中直接节点的类型,里面封装了ChannelHandler
ChannelHandler
中方法普遍带有ChannelHandlerContext
类型的参数- 可以从中获取关键对象,如
pipeline()
、channel()
- 可以直接调用
ChannelHandler
的方法,如writeAndFlush()
ChannelOption
作用
- 用于配置 Netty 中的
Channel
常用配置
SO_BACKLOG
配置 TCP/IP 协议中,初始化服务器可连接队列的大小
SO_KEEPALIVE
配置是否保持连接存活
ChannelGroup
作用
Channel
的容器,用于存储、管理所有注册在其中的Channel
常用方法
注册 channel
addd()
广播写
writeAndFlush()
NioEventLoop
作用
- 每个
NioEventLoop
包含一个Selector
相当于经典 Reactor 模型中一个 Reactor + Handler - 保持有一个任务队列,每一轮轮询并处理事件后,可以执行其中的任务
- 以事件循环的方式处理绑定在其中的
Socket
select
:通过集成的Selector
监听绑定的Socket
的关注事件processSelectedKeys
:处理选中的 key,即处理就绪的事件runAllTasks
:执行任务队列中的所有任务
NioEventLoopGroup
作用
- 可以包含多个
NioEventLoop
- 每个
NioEventLoop
对应一个Selector
和一个线程 - 通常一个
ServerSocketChannel
对应一个NioEventLoop
- 每个
- 可以分为两组协同作业(常见于服务端)
BossGroup
:负责 accept,通常只有一个NioEventLoop
WorkerGroup
:负责读写,通常有多个NioEventLoop
- 通过
chooser.next()
接口获取某个NioEventLoop
进行处理当前的SocketChannel
常用方法
优雅停机(断开连接,关闭线程)
shutdownGracefull()
Unpooled
作用
- Netty 提供的缓冲区操作工具类
常用方法
初始化 ByteBuf
copiedBuffer(CharSequence, Charset)
开辟 ByteBuf
buffer(size)
ByteBuf
作用
- Netty 提供的字节缓冲区
- 效率比 NIO 的 ByteBuffer 高
- 不需要反转
flip()
重要属性
capacity
容量,是 ByteBuf
内部用于存放数据的容器的大小,而不是实际数据量
统一由 capacity()
返回,真实获取方式随具体实现变化,如 array.length
,capacity
readIndex
下一个读入的位置
writeIndex
下一个读入的位置
属性关系图
常用方法
长度
capacity()
数据写入
writeByte
向缓冲区写入字节
writerIndex 会 +1
读取数据
readByte()
从缓冲区读取字节
readerIndex 会 +1
获取读指针
readerIndex()
读指针指向即将被读的位置
获取写指针
writerIndex()
写指针指向即将被写的位置
读取数据
getByte(index)
获取指定 index 的字节
不影响 readIndex
按 index 范围读取字符串
getCharSequence(start,end,charset)
是否有数组
hasArray()
如果返回 true 才能安全的 array()
、arrayOffset()
获取 byte 数组
array()
获取字节数组中第一个字节的偏移量
arrayOffset()
获取可读字节数
readableBytes()
参考 属性关系图