在理解了服务端接受链接,客户端建立链接的流程后,就来到了最为重要的写入环节,毕竟建立TCP链接不是用来做摆设,是用来实实在在的传输数据使用的。
读取的流程在这里有分析,不再进行过多描述
NioSocketChannel 读取信息
实例
@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {//其他业务逻辑//写入响应数据ctx.write(msg);}
对Netty有一点了解的同志对这里都比较熟悉,这里就是处理业务逻辑的地方了,我这里写的比较浅,真实的业务可能需要使用线程池来处理,不阻塞worker线程或者是boss线程。
那么在ctx.write中又发生了什么。
众所周知, Context 是上下文的概念,ChannelHandlerContext则表明是ChannelHandler的上下文,handler的串联则是由pipeline来进行连贯的,因此这里write触发到达的第一站即是 DefaultChannelPipeline 。随后的就是责任链模式的处理,最终抵达头部的write,在头部则是由unsafe来进行处理的
@Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {unsafe.write(msg, promise);}
@Overridepublic final void write(Object msg, ChannelPromise promise) {msg = filterOutboundMessage(msg);int size = pipeline.estimatorHandle().size(msg);outboundBuffer.addMessage(msg, size, promise);}
public void addMessage(Object msg, int size, ChannelPromise promise) {Entry entry = Entry.newInstance(msg, size, total(msg), promise);//.. 还有一个比较重要的东西在这里跳过了// increment pending bytes after adding message to the unflushed arrays.// See https://github.com/netty/netty/issues/1619incrementPendingOutboundBytes(entry.pendingSize, false);}
在理解了pipeline的处理思路后,netty一个整体的写入就没有这么复杂了,但是这里还涉及到一个数据量的问题,放到后边说
