@Override
protected int doReadBytes(ByteBuf byteBuf) throws Exception {
return byteBuf.writeBytes(javaChannel(), byteBuf.writableBytes());//javaChannel()方法返回的就是java.nio.SocketChannel
}
这里涉及到ByteBuf与通道打交道,最终还是会落到java.nio.Channel和java.nio.ByteBuffer上去,所以下文我也觉得有必要深究一下整个API的调用,增强对java.nio原生api的使用。
代码@7,如果没有读到可用数据,则回收刚申请的ByteBuf,如果读到的数据小于0,则说明需要将通道关闭。设置close=true,并跳出循环。
代码@8,将读到的内容(ByteBuf)通过管道传播到各个Handler,此时Handler的处理,默认都会在IO线程中处理。
代码@9,如果本次读到的字节数小于分配ByteBuf的可写字节数,说明该通道已经没有数据可读,结束本次循环。
代码@10,再次从通道中读取,直到读取次数已经超过配置的最大预读取次数,maxMessagesPreRead,如果是ServerChannel或AbstractNioChannel,则默认为16,其他的默认为1。
代码@11,触发读完成事件。
代码@12,该方法非常重要,IO线程将本次读取的字节数反馈给 接收ByteBuf分配器,方便下一次分配合理的ByteBuf,足够用,但不能超过太多。
代码@13,如果发生异常触发异常事件。
对整个通道读事件处理,上述是主要的处理流程,接下来重点分析如下两个方面代码@4: RecvByteBufAllocator和代码@8
2.1 RecvByteBuffAllocator系列类分析
/**
-
Allocates a new receive buffer whose capacity is probably large enough to read all inbound data and small enough
-
not to waste its space.
*/
public interface RecvByteBufAllocator {
/**
-
Creates a new handle. The handle provides the actual operations and keeps the internal information which is
-
required for predicting an optimal buffer capacity.
*/
Handle newHandle();
interface Handle {
/**
-
Creates a new receive buffer whose capacity is probably large enough to read all inbound data and small
-
enough not to waste its space.
*/
ByteBuf