前言
案例上手Netty,虽然代码也写了很多注释,但也建议先了解下Netty中的一些术语概念,方便理解。废话不说,开车!
什么是Netty?
Netty是一个异步事件驱动的网络应用框架,可以快速地开发网络应用程序。它极大地简化了TCP和UDP等网络编程。
Netty的特点
- Netty是一个异步事件驱动的网络应用程序框架
Netty核心概念
Channel
管道、对Socket进行了封装,通过一组API,将Socket操作变的简单。通过它来进行数据的传输
EventLoopGroup
EventLoopGroup是EventLoop的线程池,包含很多的EventLoop。
Netty 为每个 Channel 分配了一个 EventLoop,用于处理用户连接请求、对用户请求的处理等所有事件。
EventLoop 本身只是一个线程驱动,在其生命周期内只会绑定一个线程,让该线程处理一个Channel的所有I/O事件。
一个Channel一旦与一个EventLoop相绑定,则在 Channel 的整个生命周期内是不会也不能发生变化。但一个 EventLoop可以与多个 Channel 相绑定。
ServerBootStrap
用于配置整个 Netty 代码,将各个组件关联起来。服务端使用的是 ServerBootStrap,而客户端使用的是则BootStrap。
ChannelHandler 与 ChannelPipeline
ChannelHandler 是对 Channel 中数据的处理器,这些处理器可以是系统本身定义好的编/解码器,也可以是用户自定义的。这些处理器会被统一添加到一个 ChannelPipeline 的对象中,
然后按照添加的顺序对 Channel 中的数据进行依次处理。
ChannelFuture
Netty 中所有的 I/O 操作都是异步的,即操作不会立即得到返回结果,所以 Netty 中定义 了一个 ChannelFuture 对象作为这个异步操作的“代言人”,表示异步操作本身。如果想获取 到该异步操作的返回值,可以通过该异步操作对象的 addListener()方法为该异步操作添加监 听器,为其注册回调,当结果出来后马上调用执行。
Netty 的异步编程模型都是建立在 Future 与事件回调概念之上的。
拆包和粘包
Netty在基于TCP协议的网络通信中,存在拆包与粘包。拆包与粘包同时发生在数据的发送发与接收方。
发送方通过网络每发送一批二进制数据包,那么这次发送的数据包称为一帧(Frame)。在基于TCP的网络传输时,TCP会将发送方数据根据缓存情况进行拆分或重组为二进制的Frame,而接收方则需要将收到的Frame进行重组或拆分,重新恢复为发送时的ByteBuf数据。
场景描述
- 发送方要发送的ByteBuf较大,在传输之前会被TCP底层拆分为多个Frame进行发送,这个过程称为发送方拆包;接收方接收到发送方发过来的Frame,会进行合并,这个过程称为接收方粘包
- 发送方发送的ByteBuf较小,无法形成一个Frame,TCP会将很多这样的小ByteBuf合并为一个Frame进行传输,这个过程称为发送方粘包;接收方在接收到这个Frame后需要进行拆包,拆分出多个小的ByteBuf,这个过程称为接收方拆包
拆包和粘包会导致接收方接收到的数据的混乱性。但是不用怕,Netty提供了多个解决方案。
解决方案
- LineBaseFrameDecoder:按照行分隔符对数据进行拆包粘包处理
- DelimiterBasedFrameDecoder:按照指定分隔符对数据进行拆包粘包处理
- FixedLengthFrameDecoder:按照指定的长度对 Frame 中的数据进行拆粘包处理
- LengthFieldBasedFrameDecoder:基于长度域的帧解码器,用于对 LengthFieldPrepender 编码器编码后的数据进行解码
案例上手Netty代码
- httpServer 简单的http服务器
- socket 客户端服务端
- stickBag 粘包
- unpacking 拆包
- wechat 聊天室
- websocket WebSocket通信
- idle 读写超时
- heartBeat 心跳
- linebaseBaseFrameDecoder 拆包粘包解决方案:换行符
- fixedLengthFrameDecoder 拆包粘包解决方案:固定长度
- delimiterBaseFrameDecoder 拆包粘包解决方案:指定分隔符
- lengthFieldBasedFrameDecoder 拆包粘包解决方案:长度偏移量来控制
- rpc 模拟rpc
- dubbo 结合zk,模拟dubbo