ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>最近最新中文字幕在线,国产福利一区二区三区,精品国产乱码久久久久久蜜臀http://www.aygfsteel.com/DLevin/category/54919.htmlIn general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatrazh-cnFri, 04 Sep 2015 08:06:27 GMTFri, 04 Sep 2015 08:06:27 GMT60Netty3架构解æžhttp://www.aygfsteel.com/DLevin/archive/2015/09/04/427031.htmlDLevinDLevinFri, 04 Sep 2015 01:40:00 GMThttp://www.aygfsteel.com/DLevin/archive/2015/09/04/427031.htmlhttp://www.aygfsteel.com/DLevin/comments/427031.htmlhttp://www.aygfsteel.com/DLevin/archive/2015/09/04/427031.html#Feedback0http://www.aygfsteel.com/DLevin/comments/commentRss/427031.htmlhttp://www.aygfsteel.com/DLevin/services/trackbacks/427031.htmlå‰è®°å¾ˆæ—©ä»¥å‰ž®±æœ‰è¯»Nettyæºç çš„æ‰“½Ž—了åQŒç„¶è€Œç¬¬ä¸€‹Æ¡å°è¯•的时候从Netty4开始,一直抓ä¸åˆ°æ ¸å¿ƒçš„æ¡†æž¶æµ½E‹ï¼ŒåŽæ¥å› äؓ其他事情忙瀞®±æ”¾ä¸‹äº†ã€‚è¿™‹Æ¡è¶ç€ä¼‘å‡é‡æ–°æ¡è“v˜q™ä¸ª¼‹¬éª¨å¤ß_¼Œå› äØ“Netty3现在˜q˜åœ¨è¢«å¾ˆå¤šé¡¹ç›®ä‹É用,因而这‹Æ¡å†³å®šå…ˆä»ŽNetty3入手åQŒçž¬é—´å‘现Netty3çš„ä»£ç æ¯”Netty4中规中矩的多åQŒå¾ˆå¤šæ¦‚å¿µåœ¨ä»£ç æœ¬èín中都有清晰的表达åQŒæ‰€ä»¥åŠå¤©å°±æŠŠæ•´ä¸ªæ¡†æž¶çš„éª¨æž¶æžæ¸…楚了。å†è¯?a >Netty4对Netty3的改˜q›æ€È»“åQŒå›žåŽ»è¯»Netty4çš„æºç ï¼Œå而觉得轻æ¾äº†åQŒä¸€¿Uè±ç„¶å¼€æœ—的感觉ã€?br />
è®°å¾—åŽÕd¹´è¯»Jettyæºç çš„æ—¶å€™ï¼Œå› äؓ代ç å¤ªåºžå¤§ï¼Œòq¶ä¸”自己的HTTP Server的了解太ž®‘,因而åªèƒ½è‡ªåº•å‘上的一个一个模å—çš„å åŠ åQŒç›´åˆ°æœ€åŽæŠŠæ‰€ä»¥çš„æ¨¡å—˜qžæŽ¥åœ¨ä¸€èµ¯‚€Œçœ‹æ¸…它的真正核心骨架。现在读æºç åQŒå¼€å§‹ä¹ æƒ¯å…ˆæŠŠéª¨æž¶ç†æ¸…,然åŽå»¶äŽ×åˆîC¸åŒçš„器官ã€è¡€è‚‰è€Œçœ‹æ¸…整个äh体ã€?br />
本文从Reactor模å¼åœ¨Netty3中的应用åQŒå¼•出Netty3çš„æ•´ä½“æž¶æž„ä»¥åŠæŽ§åˆ¶æµ½E‹ï¼›ç„¶è€Œé™¤äº†Reactor模å¼åQŒNetty3˜q˜åœ¨ChannelPipeline中ä‹É用了Intercepting Filter模å¼åQŒè¿™ä¸ªæ¨¡å¼ä¹Ÿåœ¨Servletçš„Filter中æˆåŠŸä‹É用,因而本文还会从Intercepting Filter模å¼å‡ºå‘详细介ç»ChannelPipeline的设计ç†å¿üc€‚本文å‡è®¾è¯»è€…å·²¾l对Netty有一定的了解åQŒå› è€Œä¸ä¼šåŒ…å«è¿‡å¤šå…¥é—¨ä»‹¾l,以åŠå¸®Nettyåšå®£ä¼ çš„æ–‡å­—ã€?br />

Netty3中的Reactor模å¼

Reactor模å¼åœ¨Netty中应用éžå¸¸æˆåŠŸï¼Œå› è€Œå®ƒä¹Ÿæ˜¯åœ¨Netty中å—大肆宣传的模å¼ï¼Œå…³äºŽReactor模å¼å¯ä»¥è¯¦ç»†å‚考本人的å¦ä¸€½‹‡æ–‡ç«?a href="http://www.aygfsteel.com/DLevin/archive/2015/09/02/427045.html">《Reactor模å¼è¯¦è§£ã€?/a>åQŒå¯¹Reactor模å¼çš„实现是Netty3的基本骨æžÓž¼Œå› è€Œæœ¬ž®èŠ‚ä¼šè¯¦¾l†ä»‹¾lReactor模å¼å¦‚何应用Netty3中ã€?br />
如果诅R€ŠReactor模å¼è¯¦è§£ã€‹ï¼Œæˆ‘们知é“Reactor模å¼ç”±Handleã€Synchronous Event Demultiplexerã€Initiation Dispatcherã€Event Handlerã€Concrete Event Handleræž„æˆåQŒåœ¨Java的实现版本中åQŒChannel对应HandleåQŒSelector对应Synchronous Event DemultiplexeråQŒåƈ且Netty3˜q˜ä‹É用了两层ReactoråQšMain Reactor用于处ç†Client的连接请求,Sub Reactor用于处ç†å’ŒClient˜qžæŽ¥åŽçš„è¯Õd†™è¯äh±‚åQˆå…³äºŽè¿™ä¸ªæ¦‚念还å¯ä»¥å‚考Doug Lea的这½‹‡PPTåQ?a >Scalable IO In JavaåQ‰ã€‚所以我们先è¦è§£å†³Netty3中ä‹É用什么类实现所有的上述模å—òq¶æŠŠä»–们è”系在一èµïLš„åQŒä»¥NIO实现方å¼ä¸ÞZ¾‹åQ?br />
æ¨¡å¼æ˜¯ä¸€¿U抽象,但是在实çŽîC¸­åQŒç»å¸æ€¼šå› äؓ语言ç‰ÒŽ€§ã€æ¡†æž¶å’Œæ€§èƒ½éœ€è¦è€Œåšä¸€äº›æ”¹å˜ï¼Œå› è€ŒNetty3对Reactor模å¼çš„实现有一套自å·Þqš„设计åQ?br />1. ChannelEventåQ?/strong>Reactor是基于事件编½E‹çš„åQŒå› è€Œåœ¨Netty3中ä‹É用ChannelEvent抽象的表达Netty3内部å¯ä»¥äº§ç”Ÿçš„å„¿U事ä»Óž¼Œæ‰€æœ‰è¿™äº›äº‹ä»¶å¯¹è±¡åœ¨Channels帮助¾cÖM¸­äº§ç”ŸåQŒåƈ且由它将事äšg推入到ChannelPipeline中,ChannelPipelineæž„å¾ChannelHandler½Ž¡é“åQŒChannelEvent‹¹ç»˜q™ä¸ª½Ž¡é“实现所有的业务逻辑处ç†ã€‚ChannelEvent对应的事件有åQšChannelStateEvent表示Channel状æ€çš„å˜åŒ–事äšgåQŒè€Œå¦‚果当å‰Channel存在Parent ChannelåQŒåˆ™è¯¥äº‹ä»¶è¿˜ä¼šä¼ é€’到Parent Channelçš„ChannelPipeline中,如OPENã€BOUNDã€CONNECTEDã€INTEREST_OPS½{‰ï¼Œè¯¥äº‹ä»¶å¯ä»¥åœ¨å„ç§ä¸åŒå®žçŽ°çš„Channelã€ChannelSink中äñ”生;MessageEvent表示从Socketä¸­è¯»å–æ•°æ®å®Œæˆã€éœ€è¦å‘Socketå†™æ•°æ®æˆ–ChannelHandler对当å‰Messageè§£æž(如Decoderã€Encoder)åŽè§¦å‘的事äšgåQŒå®ƒç”±NioWorkerã€éœ€è¦å¯¹Messageåšè¿›ä¸€æ­¥å¤„ç†çš„ChannelHandler产生åQ›WriteCompletionEvent表示写完æˆè€Œè§¦å‘的事äšgåQŒå®ƒç”±NioWorker产生åQ›ExceptionEvent表示在处ç†è¿‡½E‹ä¸­å‡ºçŽ°çš„ExceptionåQŒå®ƒå¯ä»¥å‘生在å„个构件中åQŒå¦‚Channelã€ChannelSinkã€NioWorkerã€ChannelHandler中;IdleStateEventç”±IdleStateHandler触å‘åQŒè¿™ä¹Ÿæ˜¯ä¸€ä¸ªChannelEventå¯ä»¥æ— ç¼æ‰©å±•的例å­ã€‚注åQšåœ¨Netty4åŽï¼Œå·²ç»æ²¡æœ‰ChannelEvent¾c»ï¼Œæ‰€æœ‰ä¸åŒäº‹ä»‰™ƒ½ç”¨å¯¹åº”方法表达,˜q™ä¹Ÿæ„味˜q™ChannelEventä¸å¯æ‰©å±•åQŒNetty4采用在ChannelInboundHandler中加入userEventTriggered()æ–ÒŽ³•æ¥å®žçŽ°è¿™¿U扩展,具体å¯ä»¥å‚è€?a >˜q™é‡Œã€?br />2. ChannelHandleråQ?/strong>在Netty3中,ChannelHandler用于表示Reactor模å¼ä¸­çš„EventHandler。ChannelHandleråªæ˜¯ä¸€ä¸ªæ ‡è®°æŽ¥å£ï¼Œå®ƒæœ‰ä¸¤ä¸ªå­æŽ¥å£ï¼šChannelDownstreamHandlerå’ŒChannelUpstreamHandleråQŒå…¶ä¸­ChannelDownstreamHandlerè¡¨ç¤ºä»Žç”¨æˆ·åº”ç”¨ç¨‹åºæµå‘Netty3内部直到å‘Socket写数æ®çš„½Ž¡é“åQŒåœ¨Netty4中改å䨓ChannelOutboundHandleråQ›ChannelUpstreamHandler表示数æ®ä»ŽSocket˜q›å…¥Netty3内部å‘用户应用程åºåšæ•°æ®å¤„ç†çš„管é“,在Netty4中改å䨓ChannelInboundHandlerã€?br />3. ChannelPipelineåQ?/strong>用于½Ž¡ç†ChannelHandler的管é“,æ¯ä¸ªChannel一个ChannelPipeline实例åQŒå¯ä»¥è¿è¡Œè¿‡½E‹ä¸­åЍæ€çš„å‘这个管é“中æ·ÕdŠ ã€åˆ é™¤ChannelHandleråQˆç”±äºŽå®žçŽ°çš„é™åˆ¶åQŒåœ¨æœ€æœ«ç«¯çš„ChannelHandlerå‘åŽæ·ÕdŠ æˆ–åˆ é™¤ChannelHandlerä¸ä¸€å®šåœ¨å½“剿‰§è¡Œ‹¹ç¨‹ä¸­è“v效,å‚è€?a >˜q™é‡ŒåQ‰ã€‚ChannelPipeline内部¾l´æŠ¤ä¸€ä¸ªChannelHandlerçš„åŒå‘链表,它以Upstream(Inbound)æ–¹å‘为正å‘,Downstream(Outbound)æ–¹å‘为方å‘。ChannelPipeline采用Intercepting Filter模å¼å®žçްåQŒå…·ä½“å¯ä»¥å‚è€?a href="http://www.aygfsteel.com/DLevin/archive/2015/09/03/427086.html">˜q™é‡ŒåQŒè¿™ä¸ªæ¨¡å¼çš„实现在åŽä¸€èЂ䏭˜q˜æ˜¯è¯¦ç»†ä»‹ç»ã€?br />4. NioSelectoråQ?/strong>Netty3使用NioSelectoræ¥å­˜æ”¾SelectoråQˆSynchronous Event DemultiplexeråQ‰ï¼Œæ¯ä¸ªæ–îCñ”生的NIO Channel都员q™ä¸ªSelector注册自己以让˜q™ä¸ªSelector监嬘q™ä¸ªNIO Channel中å‘生的事äšgåQŒå½“事äšgå‘生æ—Óž¼Œè°ƒç”¨å¸®åŠ©¾c»Channels中的æ–ÒŽ³•生æˆChannelEvent实例åQŒå°†è¯¥äº‹ä»¶å‘é€åˆ°˜q™ä¸ªNetty Channel对应的ChannelPipeline中,而交¾l™å„¾U§ChannelHandler处ç†ã€‚其中在å‘Selector注册NIO Channelæ—Óž¼ŒNetty Channel实例以Attachmentçš„åÅžå¼ä¼ å…¥ï¼Œè¯¥Netty Channel在其内部的NIO Channel事äšgå‘生æ—Óž¼Œä¼šä»¥Attachmentçš„åÅžå¼å­˜åœ¨äºŽSelectionKey中,因而æ¯ä¸ªäº‹ä»¶å¯ä»¥ç›´æŽ¥ä»Ž˜q™ä¸ªAttachment中获å–相关链的Netty ChannelåQŒåƈ从Netty Channel中获å–与之相兌™”çš„ChannelPipelineåQŒè¿™ä¸ªå®žçŽ°å’ŒDoug Leaçš?a >Scalable IO In Java一模一栗÷€‚å¦å¤–Netty3˜q˜é‡‡ç”¨äº†Scalable IO In Java中相åŒçš„Main Reactorå’ŒSub Reactor设计åQŒå…¶ä¸­NioSelector的两个实玎ͼšBosså³äØ“Main ReactoråQŒNioWorker为Sub Reactor。Boss用æ¥å¤„ç†æ–°è¿žæŽ¥åŠ å…¥çš„äº‹äšgåQŒNioWorker用æ¥å¤„ç†å„个˜qžæŽ¥å¯¹Socket的读写事ä»Óž¼Œå…¶ä¸­Boss通过NioWorkerPool获å–NioWorker实例åQŒNetty3模å¼ä½¿ç”¨RoundRobinæ–¹å¼æ”‘Ö›žNioWorker实例。更形象一点的åQŒå¯ä»¥é€šè¿‡Scalable IO In Java的这张图表达åQ?br />
若与Ractor模å¼å¯¹åº”åQŒNioSelector中包å«äº†Synchronous Event DemultiplexeråQŒè€ŒChannelPipeline中管ç†ç€æ‰€æœ‰EventHandleråQŒå› è€ŒNioSelectorå’ŒChannelPipelineå…±åŒæž„æˆäº†Initiation Dispatcherã€?br />5. ChannelSinkåQ?/strong>在ChannelHandler处ç†å®Œæˆæ‰€æœ‰é€»è¾‘需è¦å‘客户端写å“åº”æ•°æ®æ—Óž¼Œä¸€èˆ¬ä¼šè°ƒç”¨Netty Channel中的writeæ–ÒŽ³•åQŒç„¶è€Œåœ¨˜q™ä¸ªwriteæ–ÒŽ³•å®žçŽ°ä¸­ï¼Œå®ƒä¸æ˜¯ç›´æŽ¥å‘其内部的Socket写数æ®ï¼Œè€Œæ˜¯äº¤ç»™Channels帮助¾c»ï¼Œå†…部创å¾DownstreamMessageEventåQŒåå‘从ChannelPipeline的管é“中‹¹è¿‡åŽ»ï¼Œç›´åˆ°½W¬ä¸€ä¸ªChannelHandler处ç†å®Œæ¯•åQŒæœ€åŽäº¤¾l™ChannelSink处ç†åQŒä»¥é¿å…é˜Õd¡žå†™è€Œåª„å“程åºçš„åžåé‡ã€‚ChannelSinkž®†è¿™ä¸ªMessageEventæäº¤¾l™Netty Channel中的writeBufferQueueåQŒæœ€åŽNioWorker会等到这个NIO Channelå·²ç»å¯ä»¥å¤„ç†å†™äº‹ä»¶æ—¶æ— é˜»å¡žçš„å‘这个NIO Channel写数æ®ã€‚è¿™ž®±æ˜¯ä¸Šå›¾çš„send是从SubReactor直接出å‘的原因ã€?br />6. ChannelåQ?/strong>Netty有自å·Þqš„Channel抽象åQŒå®ƒæ˜¯ä¸€ä¸ªèµ„æºçš„容器åQŒåŒ…å«äº†æ‰€æœ‰ä¸€ä¸ªè¿žæŽ¥æ¶‰åŠåˆ°çš„æ‰€æœ‰èµ„æºçš„饮用åQŒå¦‚ž®è£…NIO Channelã€ChannelPipelineã€Bossã€NioWorkerPool½{‰ã€‚å¦å¤–它˜q˜æä¾›äº†å‘内部NIO Channel写å“应数æ®çš„æŽ¥å£writeã€è¿žæŽ?¾l‘定到æŸä¸ªåœ°å€çš„connect/bind接壽{‰ï¼Œä¸ªäh感觉虽然对Channel本èínæ¥è¯´åQŒå› ä¸ºå®ƒž®è£…了NIO ChannelåQŒå› è€Œè¿™äº›æŽ¥å£å®šä¹‰åœ¨˜q™é‡Œæ˜¯åˆç†çš„åQŒä½†æ˜¯å¦‚果考虑到Netty的架构,它的Channelåªæ˜¯ä¸€ä¸ªèµ„æºå®¹å™¨ï¼Œæœ‰è¿™ä¸ªChannel实例ž®±å¯ä»¥å¾—到和它相关的基本所有资æºï¼Œå› è€Œè¿™¿Uwriteã€connectã€bind动作ä¸åº”该å†ç”±å®ƒè´Ÿè´£åQŒè€Œæ˜¯åº”该由其他类æ¥è´Ÿè´£ï¼Œæ¯”如在Netty4中就在ChannelHandlerContextæ·ÕdŠ äº†writeæ–ÒŽ³•åQŒè™½ç„¶netty4òq¶æ²¡æœ‰åˆ é™¤Channel中的write接å£ã€?br />

Netty3中的Intercepting Filter模å¼

如果说Reactoræ¨¡å¼æ˜¯Netty3的骨æžÓž¼Œé‚£ä¹ˆIntercepting Filter模å¼åˆ™æ˜¯Netty的中枢。Reactor模å¼ä¸»è¦åº”用在Netty3的内部实玎ͼŒå®ƒæ˜¯Netty3å…ähœ‰è‰¯å¥½æ€§èƒ½çš„基¼‹€åQŒè€ŒIntercepting Filter模å¼åˆ™æ˜¯ChannelHandler¾l„åˆå®žçŽ°ä¸€ä¸ªåº”ç”¨ç¨‹åºé€»è¾‘的基¼‹€åQŒåªæœ‰å¾ˆå¥½çš„ç†è§£äº†è¿™ä¸ªæ¨¡å¼æ‰èƒ½ä‹É用好NettyåQŒç”šè‡Œ™ƒ½å¾—心应手ã€?br />
关于Intercepting Filter模å¼çš„详¾l†ä»‹¾lå¯ä»¥å‚è€?a href="http://www.aygfsteel.com/DLevin/archive/2015/09/03/427086.html">˜q™é‡ŒåQŒæœ¬èЂ䏻è¦ä»‹¾lNetty3中对Intercepting Filter模å¼çš„实玎ͼŒå…¶å®žž®±æ˜¯DefaultChannelPipeline对Intercepting Filter模å¼çš„实现。在上文有æåˆ°Netty3çš„ChannelPipeline是ChannelHandler的容器,用于存储与管ç†ChannelHandleråQŒåŒæ—¶å®ƒåœ¨Netty3中也起到桥æ¢çš„作用,å›_®ƒæ˜¯è¿žæŽ¥Netty3内部到所有ChannelHandler的桥æ¢ã€‚作为ChannelPipeline的实现者DefaultChannelPipelineåQŒå®ƒä½¿ç”¨ä¸€ä¸ªChannelHandlerçš„åŒå‘链表æ¥å­˜å‚¨åQŒä»¥DefaultChannelPipelineContextä½œäØ“èŠ‚ç‚¹åQ?br />
public interface ChannelHandlerContext {
    Channel getChannel();

    ChannelPipeline getPipeline();

    String getName();

    ChannelHandler getHandler();

    
boolean canHandleUpstream();
    
boolean canHandleDownstream();
    
void sendUpstream(ChannelEvent e);
    
void sendDownstream(ChannelEvent e);
    Object getAttachment();

    
void setAttachment(Object attachment);
}

private final class DefaultChannelHandlerContext implements ChannelHandlerContext {
   
volatile DefaultChannelHandlerContext next;
   
volatile DefaultChannelHandlerContext prev;
   
private final String name;
   
private final ChannelHandler handler;
   
private final boolean canHandleUpstream;
   
private final boolean canHandleDownstream;
   
private volatile Object attachment;
.....
}
在DefaultChannelPipeline中,它存储了和当å‰ChannelPipeline相关è”çš„Channelã€ChannelSink以åŠChannelHandler链表的headã€tailåQŒæ‰€æœ‰ChannelEvent通过sendUpstreamã€sendDownstreamä¸ºå…¥å£æµ¾l整个链表:
public class DefaultChannelPipeline implements ChannelPipeline {
    
private volatile Channel channel;
    
private volatile ChannelSink sink;
    
private volatile DefaultChannelHandlerContext head;
    
private volatile DefaultChannelHandlerContext tail;
......
    
public void sendUpstream(ChannelEvent e) {
        DefaultChannelHandlerContext head 
= getActualUpstreamContext(this.head);
        
if (head == null) {
            
return;
        }
        sendUpstream(head, e);
    }

    
void sendUpstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
        
try {
            ((ChannelUpstreamHandler) ctx.getHandler()).handleUpstream(ctx, e);
        } 
catch (Throwable t) {
            notifyHandlerException(e, t);
        }
    }

    
public void sendDownstream(ChannelEvent e) {
        DefaultChannelHandlerContext tail 
= getActualDownstreamContext(this.tail);
        
if (tail == null) {
            
try {
                getSink().eventSunk(
this, e);
                
return;
            } 
catch (Throwable t) {
                notifyHandlerException(e, t);
                
return;
            }
        }
        sendDownstream(tail, e);
    }

    
void sendDownstream(DefaultChannelHandlerContext ctx, ChannelEvent e) {
        
if (e instanceof UpstreamMessageEvent) {
            
throw new IllegalArgumentException("cannot send an upstream event to downstream");
        }
        
try {
            ((ChannelDownstreamHandler) ctx.getHandler()).handleDownstream(ctx, e);
        } 
catch (Throwable t) {
            e.getFuture().setFailure(t);
            notifyHandlerException(e, t);
        }
    }
对Upstream事äšgåQŒå‘åŽæ‰¾åˆ°æ‰€æœ‰å®žçŽîCº†ChannelUpstreamHandler接å£çš„ChannelHandler¾l„æˆé“¾ï¼ˆgetActualUpstreamContext()åQ?/span>åQŒè€Œå¯¹Downstream事äšgåQŒå‘剿‰¾åˆ°æ‰€æœ‰å®žçŽîCº†ChannelDownstreamHandler接å£çš„ChannelHandler¾l„æˆé“¾ï¼ˆgetActualDownstreamContext()åQ‰ï¼š
    private DefaultChannelHandlerContext getActualUpstreamContext(DefaultChannelHandlerContext ctx) {
        
if (ctx == null) {
            
return null;
        }
        DefaultChannelHandlerContext realCtx 
= ctx;
        
while (!realCtx.canHandleUpstream()) {
            realCtx 
= realCtx.next;
            
if (realCtx == null) {
                
return null;
            }
        }
        
return realCtx;
    }
    
private DefaultChannelHandlerContext getActualDownstreamContext(DefaultChannelHandlerContext ctx) {
        
if (ctx == null) {
            
return null;
        }
        DefaultChannelHandlerContext realCtx 
= ctx;
        
while (!realCtx.canHandleDownstream()) {
            realCtx 
= realCtx.prev;
            
if (realCtx == null) {
                
return null;
            }
        }
        
return realCtx;
    }
在实际实现ChannelUpstreamHandler或ChannelDownstreamHandleræ—Óž¼Œè°ƒç”¨ ChannelHandlerContext中的sendUpstream或sendDownstreamæ–ÒŽ³•ž®†æŽ§åˆ¶æµ½E‹äº¤¾l™ä¸‹ä¸€ä¸? ChannelUpstreamHandler或下一个ChannelDownstreamHandleråQŒæˆ–调用Channel中的writeæ–ÒŽ³•å‘é€? å“应消æ¯ã€?br />
public class MyChannelUpstreamHandler implements ChannelUpstreamHandler {
    
public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
        
// handle current logic, use Channel to write response if needed.
        
// ctx.getChannel().write(message);
        ctx.sendUpstream(e);
    }
}

public class MyChannelDownstreamHandler implements ChannelDownstreamHandler {
    
public void handleDownstream(
            ChannelHandlerContext ctx, ChannelEvent e) 
throws Exception {
        
// handle current logic
        ctx.sendDownstream(e);
    }
}
当ChannelHandlerå‘ChannelPipelineContextå‘é€äº‹ä»¶æ—¶åQŒå…¶å†…部从当å‰ChannelPipelineContextèŠ‚ç‚¹å‡ºå‘æ‰‘Öˆ°ä¸‹ä¸€ä¸ªChannelUpstreamHandler或ChannelDownstreamHandler实例åQŒåƈå‘å…¶å‘é€ChannelEventåQŒå¯¹äºŽDownstream链,如果到达铑ְ¾åQŒåˆ™ž®†ChannelEventå‘é€ç»™ChannelSinkåQ?br />
public void sendDownstream(ChannelEvent e) {
    DefaultChannelHandlerContext prev 
= getActualDownstreamContext(this.prev);
   
if (prev == null) {
       
try {
            getSink().eventSunk(DefaultChannelPipeline.
this, e);
        } 
catch (Throwable t) {
            notifyHandlerException(e, t);
        }
    } 
else {
        DefaultChannelPipeline.
this.sendDownstream(prev, e);
    }
}

public void sendUpstream(ChannelEvent e) {
    DefaultChannelHandlerContext next 
= getActualUpstreamContext(this.next);
   
if (next != null) {
        DefaultChannelPipeline.
this.sendUpstream(next, e);
    }
}
æ­£æ˜¯å› äØ“˜q™ä¸ªå®žçްåQŒå¦‚果在一个末ž®„¡š„ChannelUpstreamHandler中先¿U»é™¤è‡ªå·±åQŒåœ¨å‘末ž®¾æ·»åŠ ä¸€ä¸ªæ–°çš„ChannelUpstreamHandleråQŒå®ƒæ˜¯æ— æ•ˆçš„åQŒå› ä¸ºå®ƒçš„nextå·²ç»åœ¨è°ƒç”¨å‰ž®±å›ºå®šè®¾¾|®äØ“null了ã€?br />
ChannelPipelineä½œäØ“ChannelHandler的容器,它还æä¾›äº†å„¿U增ã€åˆ ã€æ”¹ChannelHandler链表中的æ–ÒŽ³•åQŒè€Œä¸”如果æŸä¸ªChannelHandler˜q˜å®žçŽîCº†LifeCycleAwareChannelHandleråQŒåˆ™è¯¥ChannelHandler在被æ·ÕdŠ ˜q›ChannelPipeline或从中删除时都会得到åŒå¿—åQ?br />
public interface LifeCycleAwareChannelHandler extends ChannelHandler {
    
void beforeAdd(ChannelHandlerContext ctx) throws Exception;
    
void afterAdd(ChannelHandlerContext ctx) throws Exception;
    
void beforeRemove(ChannelHandlerContext ctx) throws Exception;
    
void afterRemove(ChannelHandlerContext ctx) throws Exception;
}

public interface ChannelPipeline {
    
void addFirst(String name, ChannelHandler handler);
    
void addLast(String name, ChannelHandler handler);
    
void addBefore(String baseName, String name, ChannelHandler handler);
    
void addAfter(String baseName, String name, ChannelHandler handler);
    
void remove(ChannelHandler handler);
    ChannelHandler remove(String name);

    
<extends ChannelHandler> T remove(Class<T> handlerType);
    ChannelHandler removeFirst();

    ChannelHandler removeLast();

    
void replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
    ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);

    
<extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler);
    ChannelHandler getFirst();

    ChannelHandler getLast();

    ChannelHandler get(String name);

    
<extends ChannelHandler> T get(Class<T> handlerType);
    ChannelHandlerContext getContext(ChannelHandler handler);

    ChannelHandlerContext getContext(String name);

    ChannelHandlerContext getContext(Class
<? extends ChannelHandler> handlerType);
    
void sendUpstream(ChannelEvent e);
    
void sendDownstream(ChannelEvent e);
    ChannelFuture execute(Runnable task);

    Channel getChannel();

    ChannelSink getSink();

    
void attach(Channel channel, ChannelSink sink);
    
boolean isAttached();
    List
<String> getNames();
    Map
<String, ChannelHandler> toMap();
}

在DefaultChannelPipelineçš„ChannelHandler链æ¡çš„å¤„ç†æµ½E‹äØ“åQ?br />

å‚考:

《Netty主页�/a>
《Nettyæºç è§£è¯»åQˆå››åQ‰Netty与Reactor模å¼ã€?/a>
《Netty代ç åˆ†æžã€?/a>
Scalable IO In Java
Intercepting Filter Pattern


]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÒÁ´¨ÏØ| ÏìË®ÏØ| ³Î½­ÏØ| °²ÔóÏØ| ÕÑËÕÏØ| Á鱦ÊÐ| å§ÑôÏØ| Á¬ÔƸÛÊÐ| Çð±±ÏØ| ÎߺþÏØ| ¹ðÁÖÊÐ| »³ÈÊÏØ| ÉÏÈÄÏØ| ˼ÄÏÏØ| ´óÀíÊÐ| ÀèÆ½ÏØ| ¹ãÆ½ÏØ| ´óÒ¦ÏØ| Äϲ¿ÏØ| ÏóÖÝÏØ| ½­ÃÅÊÐ| á·É½ÏØ| ÇåÐìÏØ| ²ÊƱ| Äϲ¿ÏØ| À³Î÷ÊÐ| ¸ñ¶ûľÊÐ| ¾¸Ô¶ÏØ| ÑôË·ÏØ| ÔÞ»ÊÏØ| ÑôÐÂÏØ| ¼¯ÏÍÏØ| ¸ö¾ÉÊÐ| µ¤¶«ÊÐ| µ¾³ÇÏØ| Âú³ÇÏØ| ËÉÔ­ÊÐ| ¹®ÒåÊÐ| ²©ÂÞÏØ| ãÏÖÐÊÐ| ׯÀËÏØ|