channelRead()和channelReadComplete() 方法的区别是什么?
我在看ChannelInboundHandler源码的时候,看到了这两个方法,英语注释,单词也都认识。但是还是没明白注释的意思?可以给我解释一下吗?
源码如下:
/**
* Invoked when the current {@link Channel} has read a message from the peer.
*/
void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;
/**
* Invoked when the last message read by the current read operation has been consumed by
* {@link #channelRead(ChannelHandlerContext, Object)}. If {@link ChannelOption#AUTO_READ} is off, no further
* attempt to read an inbound data from the current {@link Channel} will be made until
* {@link ChannelHandlerContext#read()} is called.
*/
void channelReadComplete(ChannelHandlerContext ctx) throws Exception;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当
channel
上面有数据到来时会触发channelRead
事件,当数据到来时,eventLoop
被唤醒继而调用channelRead
方法处理数据。channelReadComplete
事件参考 How does netty determine when a read is complete?大致意思是
eventLoop
被到来的数据唤醒后read
数据并包装成msg
,然后将msg
作为参数调用channelRead
方法,期间做个判断,read
到0个字节或者是read
到的字节数小于buffer
的容量,满足以上条件就会调用channelReadComplete
方法。楼上说的是对的,但是翻过来解释可能会更加容易理解。首先看下面这段代码,这个例子是Netty in action里的第二章里的例子,这个是Server的回调方法。
channelRead表示接收消息,可以看到msg转换成了ByteBuf,然后打印,也就是把Client传过来的消息打印了一下,你会发现每次打印完后,channelReadComplete也会调用,如果你试着传一个超长的字符串过来,超过1024个字母长度,你会发现channelRead会调用多次,而channelReadComplete只调用一次。
所以这就比较清晰了吧,因为ByteBuf是有长度限制的,所以超长了,就会多次读取,也就是调用多次channelRead,而channelReadComplete则是每条消息只会调用一次,无论你多长,分多少次读取,只在该条消息最后一次读取完成的时候调用,所以这段代码把关闭Channel的操作放在channelReadComplete里,放到channelRead里可能消息太长了,结果第一次读完就关掉连接了,后面的消息全丢了。