Netty之channel

      我们知道,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接口中一些重要的方法定义:

  1. ChannelId id();

  2. EventLoop eventLoop();

  3. Channel parent();

  4. ChannelConfig config();

  5. boolean isOpen();

  6. boolean isRegistered();

  7. boolean isActive();

  8. boolean isWritable();

  9. ChannelPipeline pipeline();

  10. ByteBufAllocator alloc();

  11. Channel read();

  12. Channel flush();

  13. // 以下方法继承自父接口

  14. ChannelFuture bind(SocketAddress localAddress,ChannelPromise promise);

  15. ChannelFuture connect(SocketAddress remoteAddress,SocketAddress localAddress,ChannelPromise promise);

  16. ChannelFuture disconnect(ChannelPromise promise);

  17. ChannelFuture close(ChannelPromise promise);

  18. ChannelFuture deregister(ChannelPromise promise);

  19. ChannelOutboundInvoker read();

  20. ChannelFuture write(Object msg,ChannelPromise promise);

  21. ChannelOutboundInvoker flush();

  22. 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的引用保存起来,以便后面使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值