ChunkedWriteHandler

write方法将数据包装成PendingWrite塞入队列
flush方法:从队列里面取出数据对于如果是ChunkedInput类型的数据会自动切割
支持文件,stream,input,httppostrequest和websocketinput几种切割。
在这切割期间设置了endofInput 每次发送数据完了之后看看是否到了endofInput
如果没有 在检测channel是否可写 如果可写 则在添加监听者监听发送流程
不可写则在上面任务写完之后重新判断是否可写 如果可写就结束,但是
其也重写了channelWritabilityChanged方法,如果可写还会继续发送,
所以这个ChunkedWriteHandler的大致逻辑就是,首先Write方法都会把数据写入队列
等到flush的时候才是把数据变成上述几种类型,然后发送到后续的handler 进行发送
这个过程中如果阻塞则通过注册监听以及channelWritabilityChanged在通道可写的情况下继续去write

Netty 只保证了我们每一个writeAndFlush方法会传递一个完整的数据(比如我们一次发送10M,对端不会只收到5M 然后
在收到其他消息的数据 最终在收到剩余5M)
同理 我们这边的ChunkedWriteHandler 只保证队列中的每一个元素是一次性发送
而队列之间的顺序只是保持大致顺序,中间也会有其他的消息插入到我们的flusedEntry里面。
比如我们通过ChunkedWriteHandler 传递我们的file
原理是我们先将我们的file变成ChunkedFile,指定chunkSize和file的startoffset以及endoffset

那么我们每次最多生成chunkSize大小的message,每次分配堆内bytebuf,然后将该bytebuf填充满
最后发出去,然后只要channel一直可写就一直发送,
所以这边的有点就算每次只发送指定大小,且可以利用pool 来避免内存无限大。
注意ChunkedWriteHandler 一般的都是放在channelHandler最前面,这样出入站信息都是通过他发送到headcontext,这样我们所有的消息都是被当成一个个队列元素塞入队列,然后每次取出一个消息发送,如果是非ChunkedInput则直接发送,如果是ChunkedInput则每次发送chunksize的,接收端可以根据Unpooled.EMPTY_BUFFER来判断是否已经接受完全了

那么使用ChunkedWriteHandler或者直接包装成fileRegion的区别在于什么? 前者我们可以掌控文件发送的细节过程,后者却无法感知

你可能感兴趣的:(ChunkedWriteHandler)