概述
我们知道,netty中的ByteBuf组件主要是为了替代NIO中的ByteBuffer类而重新设计的,与此类似的还有一个组件:Channel。
Channel组件是为了替代Socket而重新设计的,Channel的接口所提供给我们的API,大大地降低了直接使用Socket时的复杂性。本篇文章,就让我们来了解下netty中的Channel组件。
一.Channel定义
Netty中对Channel是这样定义的:
A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind.
简单来说Channel是与网络套接字相关的,一个具有诸如:读、写、连接、绑定等能力的组件。
通过Channel我们可以得到以下的数据:
-
一个Channel的当前状态,比如该通道是打开状态还是连接的状态
-
可以得到该Channel的ChannelConfig,并可以得到相关的配置信息
-
该Channel所支持的IO操作:读、写、连接或者绑定
-
与该Channel绑定的用来处理该Channel上所有的事件和请求的ChannelPipeline
我们知道netty高性能的关键之一是IO模型,对于netty来说所有的IO操作都是异步的,而这都得益于Channel中所有方法的执行都是异步的。一个IO请求来了之后是立即返回的并且不保证调用结束时改IO操作已经完成了,取而代之的是:
一个IO请求来了之后,请求者会得到一个ChannelFuture的实例,该实例会在你的IO操作真正完成后(包括成功,失败,被取消)通知你,然后你就可以得到具体的IO操作的结果。
Channel是有层级关系的,一个Channel会有一个对应的parent,该parent也是一个Channel。并且根据Channel的创建不同,他的parent也会不一样。例如,一个SocketChannel连接上ServerSocketChannel之后,该SocketChannel的parent就会是该ServerSocketChannel。层次结构的语义取决于Channel使用了何种传输实现方式。比如我们可以重新定义一种Channel的实现,在该Channel上创建一个共享此通道的用来连接SSH的子通道。
需注意的是,当你在一个Channel上完成了所有的操作之后,记得要调用close()方法来释放资源,这是非常有必要的。
二.Channel的接口定义
下面让我们来看下Channel接口中一些重要的方法定义:
-
ChannelId id();
-
EventLoop eventLoop();
-
Channel parent();
-
ChannelConfig config();
-
boolean isOpen();
-
boolean isRegistered();
-
boolean isActive();
-
boolean isWritable();
-
ChannelPipeline pipeline();
-
ByteBufAllocator alloc();
-
Channel read();
-
Channel flush();
-
// 以下方法继承自父接口
-
ChannelFuture bind(SocketAddress localAddress,ChannelPromise promise);
-
ChannelFuture connect(SocketAddress remoteAddress,SocketAddress localAddress,ChannelPromise promise);
-
ChannelFuture disconnect(ChannelPromise promise);
-
ChannelFuture close(ChannelPromise promise);
-
ChannelFuture deregister(ChannelPromise promise);
-
ChannelOutboundInvoker read();
-
ChannelFuture write(Object msg,ChannelPromise promise);
-
ChannelOutboundInvoker flush();
-
ChannelFuture writeAndFlush(Object msg,ChannelPromise promise);
-
id()方法将返回一个全局唯一的ChannelId,该ChannelId由以下规则构成: 1:服务器的Mac地址 2:当前的进程ID 3:System.currentTimeMillis() 4:System.nanoTime() 5:一个随机的32位整数 6:一个顺序增长的32位整数
-
eventLoop()方法将返回分配给该Channel的EventLoop,一个EventLoop就是一个线程,用来处理连接的生命周期中所发生的事件
-
parent()方法将返回该Channel的父Channel
-
config()方法将返回该Channel的ChannelConfig,ChannelConfig中包含了该Channel的所有配置设置,并且支持热更新
-
pipeline()方法将返回该Channel所对应的ChannelPipeline
-
alloc()方法将返回分配给该Channel的ByteBufAllocator,可以用来分配ByteBuf
除了以上这些方法外,Channel还继承了ChannelOutboundInvoker接口。该接口中的大部分方法返回值都是ChannelFuture(还有一部分方法的返回值是ChannelPromise),这也证明了Channel的所有操作都是异步的说法。因为一个ChannelFuture就是一个异步方法执行结果的占位符。这个方法什么时候被执行可能取决于若干的因素,因此无法准确的预测。但是有一点可以肯定的是他将会被执行,并且所有关联在同一个Channel上的操作都被保证将以他们被调用的顺序被执行。
三.总结
以上我们对Channel有了一个大概了解,现总结一下:
-
一个Channel就相当于一个Socket
-
Channel拥有以下一些IO操作的能力,包括连接,绑定,断开,读写数据等
-
Channel中的所有方法都是异步的,方法执行的返回值是一个ChannelFuture
-
ChannelFuture可以通过添加Listener的方式在方法执行完毕的时候通知方法的调用者
-
Channel被设计为线程安全的,我们不必担心线程安全的问题,并且可以将Channel的引用保存起来,以便后面使用
最后
以上就是精明胡萝卜为你收集整理的Netty之channel的全部内容,希望文章能够帮你解决Netty之channel所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复