netty获取玩家chanel_netty源码解析(4.0)-14 Channel NIO实现:读取数据

本章分析Nio Channel的数据读取功能的实现。

Channel读取数据需要Channel和ChannelHandler配合使用,netty设计数据读取功能包括三个要素:Channel, EventLoop和ChannelHandler。Channel有个read方法,这个方法不会直接读取数据,它的作用是通知持有当前channel的eventLoop可以从这个这个channel读取数据了,这个方法被调用之后eventLoop会在channel有数据可读的时候从channel读出数据然后把数据放在channelRead事件中交给ChannelInboundHandler的channelRead方法处理,当eventLoop发现channel中暂时没时间可读会触发一个channelReadComplete事件。

read: Nio Channel通知eventLoop开始读数据

channel read方法的调用栈:

1 io.netty.channel.AbstractChannel#read2 io.netty.channel.DefaultChannelPipeline#read3 io.netty.channel.AbstractChannelHandlerContext#read4 io.netty.channel.AbstractChannelHandlerContext#invokeRead5 io.netty.channel.DefaultChannelPipeline.HeadContext#read6 io.netty.channel.AbstractChannel.AbstractUnsafe#beginRead7 io.netty.channel.nio.AbstractNioChannel#doBeginRead

调用channel的read的方法,会触发read事件,通过pipeline调用AbstractChannel unsafe的beginRead方法,这个方法的语义是通知eventLoop可以从channel读数据了,但他没有实现具体功能,把具体功能留给doBeginRead实现。doBeginRead在AbstractChannel中定义,它是一个抽象方法。AbstractNioChannel实现了这个方法:

1 @Override2 protected void doBeginRead() throwsException {3 //Channel.read() or ChannelHandlerContext.read() was called

4 if(inputShutdown) {5 return;6 }7

8 final SelectionKey selectionKey = this.selectionKey;9 if (!selectionKey.isValid()) {10 return;11 }12

13 readPending = true;14

15 final int interestOps =selectionKey.interestOps();16 if ((interestOps & readInterestOp) == 0) {17 selectionKey.interestOps(interestOps | readInterestOp);18 }19 }

这里的doBeginRead实现,只有第17行是核心代码:把readInterestOps保存是的read操作标志添加到SelectableChannel的SelectionKey中。这里的readInterestOps是一个类的属性,在AbstractNioChannel中,它没有明确的定义,只有一个抽象的定义:NIO中的一个可以可以当成read操作的的标志。在NIO中可以当成read的有SelectionKey.OP_READ和SelectionKey.OP_ACCEPT。readInterestOps在AbstractNioChannel的构造方法中使用传入的参数初始化,子类就可以根据需要确定interestOps的具体含义。

设置好beginRead之后,NioEventLoop就可以使用Selector得到检测到channel上的read事件了,下面是NioEventLoop中处理read事件的代码:

1 //io.netty.channel.nio.NioEventLoop#processSelectedKey(java.nio.channels.SelectionKey, io.netty.channel.nio.AbstractNioChannel)

2 if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {3 unsafe

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值