本章主要介绍Netty中的组件channel
一、channel概念
io.netty.channel.Channel时Netty对网络的抽象,它组合了一组功能,包括不限于网络的读、写、客户端发起连接,主动关闭连接,关闭链路,获取通信双方的地址等,还包括获取该channel的eventLoop,获取缓冲区分配类BytebufferAllocator和pipeline等。
为什么不适用JDK提供的channel,Netty自实现了channel,主要原因有:
- jdk的serverSocket,socketChannel没有统一的接口供业务开发使用,对于用于而言,没有统一的操作视图
- jdk的serverSocket,socketChannel是SPI类接口,主要职责是网络IO操作,扩展它与重新开发一个Channel工作量差不多
- Netty的channel需要配合自身的框架特性,
- 自定义channel功能上更加灵活
二、常见的API
- channel.read(),从当前channel读取数据到第一个inbound缓冲区中,如果数据被成功读取,会触发一个channelHandler.channelRead(ChannelHanlderContext context, Object)事件。读取操作完后,紧接着会触发ChannelHandler.channelReadComplete(ChannelHandlerContext context)事件,这样业务的channelhandler可判断是否还需要读取数据。
- ChannelFuture write(Object msg),将msg通过pipeline写入channel中。注意,write操作只是将数据存入到消息发送的环形数组中,并没有真正发送,调用flush操作后才会被发送。
- ChannelFuture write(Object msg, ChannelPromise promise),与write功能相同,promise负责设置写入操作的结果。
- ChannelFuture writeAndFlush(Object msg, ChannelPromise promise),相当于write和flush操作的结合
- ChannelFuture writeAndFlush(Object msg)
- ChannelFuture close( ChannelPromise promise),主动关闭当前连接,promise处理操作结果并负责通知
- ChannelFuture disconnect( ChannelPromise promise),请求断开与远程通信端的连接,promise获取操作结果的通知消息
- ChannelFuture connect(SocketAddress address),与远程地址建立连接,如果请求连接被拒绝,操作结果为ConnectException。这个操作会触发channelHandler.connect(ChannelHandlerContext context, SocketAddress address, ChannelPromise promise)事件。
- ChannelFuture bind(SocketAddress localAddress),绑定指定的本地地址,会触发事件
三、Channel的继承实现类
NioServerSocketChannel和NioSocketChannel,
UnSafe类是channel的辅助接口,所以的IO读写都是同UnSafe类完成的。
四、ChannelPipeline和ChannelHandler
ChannelPipeline和ChannelHandler的关系类似Servlet和filter的关系,channelHandler对channel进行过滤,而ChannelPipeline提供环境,持有channelHandler事件拦截器的链表。可以方便的增加和删除channelHandler来实现对channel中数据流的处理。
自定义实现channelHandler,通常只需要继承ChannelHandlerAdapter就行,对需要处理的方法进行覆盖。
用户在操作Netty不需要自己创建pipeline,因为bootstrap在启动的时候,会为每一个channel创建一个独立的pipeline。对于使用者来说,只需要将channelHandler加入到pipeline中。
ChannelPipeline支持运行时动态添加或删除handler,并且ChannelPipeline时线程安全的