Netty组件
(1)Bootstrap或ServerBootstrap
主要作用是配置整个Netty程序,串联起各个组件。
(2)ChannelHandler
主要用来处理各种事件,比如连接、数据接收、异常、数据转换等。
(3)ChannelInitializer
用来配置handler,它会提供一个ChannelPipeline,并把handler加入到ChannelPipeline。
(4)ChannelPipeline
(5)Channel
代表一个Socket链接,或者其它与IO操作相关的组件。
(6)EventLoop
为Channel处理IO操作,一个EventLoop可以为多个Channel服务。
(7)EventLoopGroup
包含多个EventLoop。
(8)Future
通过Future,可以注册一个监听,当操作执行成功或失败会自动触发。
Netty连接
当一个连接到达,Netty会注册一个channel,然后EventLoopGroup会分配一个EventLoop绑定到这个channel,当这个channel的整个生命周期过程中,都会由绑定的这个EventLoop来为它服务,而这个EventLoop就是一个线程。
配置Netty应用
利用Boostrap来配置netty应用,它有两种类型,一种用于client端:BootStrap,另一种用于Server端:ServerBootstrap。
(1)ServerBootStrap用于Server端,通过调用bind()方法绑定一个端口监听连接,BootStrap用于client端,需要调用connect()方法来连接服务端。
(2)客户端的Bootstrap一般用一个EventLoopGroup,而服务端的ServerBootStrap会用两个。第一个用于专门负责绑定端口的监听事件,第二个用于处理每个接收到的连接。
ChannelHandler
ChannelHandler有两个子类ChannelInboundHandler和ChannelOutboundHandler,如果数据是从外部流入我们的应用程序,我们就看做是inbound,相反便是outbound。
数据在各个Handler之间传递,需要调用方法中传递的ChannelHandlerContext,在netty的API中提供了两个基类ChannelOutboundHandlerAdapter和ChannelInBoundHanderAdapter,他们仅仅实现了调用ChannelHandlerContext来把消息传递给下一个Handler,因为我们只关心处理数据,因此我们可以继承这两个基类来帮助我们做这些,而我们仅需处理数据的部分即可。
当一个ChannelHandler被加入到ChannelPipeline中时,它便会获得一个ChannelHandlerContext的引用,而ChannelHandlerContext可以用来读写Netty中的数据流。因此,现在可以有两种方式来发送数据,一种是把数据直接写入Channel,一种是把数据写入ChannelHandlerContext,它们的区别是写入Channel的话,数据流会从Channel的头开始传递,而如果写入ChannelHandlerContext的话,数据流会流入管道中下一个Handler。
Encoders,Decoders
因为我们在网络传输时只能传输字节流,因此,在发送数据之前,我们必须把我们的message型转换为bytes,与之对应,我们在接收数据后,必须把接收的bytes再转换成message。我们把bytes to message这个过程称为decode, 把message to bytes称为encoder.
Netty中提供了很多现成的编码/解码器,如ByteToMessageDecoder, MessageToByteEncoder。
Decoder会覆盖InboundAdapter的ChannelRead()方法,解码字节流,然后调用ChannelHandlerContext.fireChannelRead(decodedMessage)方法把编码好的Message传递给下一个Handler。Encoder与之类似。
Domain Logic
Netty提供了一个常用的基类SimpleChannelInboundHandler<T>,其中T就是这个Handler处理的数据的类型,消息到达这个Handler时,Netty会自动调用这个Handler中的channelRead0(ChannelHandlerContext,T)方法,T是传递过来的数据对象,在这个方法中我们便可以任意写我们的逻辑。