Chan Chen Coding...

          Netty 4.0 源碼分析(五):ChannelHandlerContext和ChannelHandler

          ChannelHandlerContext接口

           1 package io.netty.channel;
           2 import io.netty.buffer.ByteBuf;
           3 import io.netty.buffer.MessageBuf;
           4 import io.netty.util.AttributeMap;
           5 import java.nio.channels.Channels;
           6 import java.util.Set;
           7 public interface ChannelHandlerContext
           8          extends AttributeMap, ChannelFutureFactory,
           9                  ChannelInboundInvoker, ChannelOutboundInvoker {
          10     Channel channel();
          11     ChannelPipeline pipeline();
          12     EventExecutor executor();
          13     String name();
          14     ChannelHandler handler();
          15     Set<ChannelHandlerType> types();
          16     boolean hasInboundByteBuffer();
          17     boolean hasInboundMessageBuffer();
          18     ByteBuf inboundByteBuffer();
          19     <T> MessageBuf<T> inboundMessageBuffer();
          20     boolean hasOutboundByteBuffer();
          21     boolean hasOutboundMessageBuffer();
          22     ByteBuf outboundByteBuffer();
          23     <T> MessageBuf<T> outboundMessageBuffer();
          24     ByteBuf replaceInboundByteBuffer(ByteBuf newInboundByteBuf);
          25     <T> MessageBuf<T> replaceInboundMessageBuffer(MessageBuf<T> newInboundMsgBuf);
          26     ByteBuf replaceOutboundByteBuffer(ByteBuf newOutboundByteBuf);
          27     <T> MessageBuf<T> replaceOutboundMessageBuffer(MessageBuf<T> newOutboundMsgBuf);
          28     boolean hasNextInboundByteBuffer();
          29     boolean hasNextInboundMessageBuffer();
          30     ByteBuf nextInboundByteBuffer();
          31     MessageBuf<Object> nextInboundMessageBuffer();
          32     boolean hasNextOutboundByteBuffer();
          33     boolean hasNextOutboundMessageBuffer();
          34     ByteBuf nextOutboundByteBuffer();
          35     MessageBuf<Object> nextOutboundMessageBuffer();
          36     boolean isReadable();
          37     void readable(boolean readable);
          38 }

           

          ChannelHandlerContext接口UML

           

          ChannelHandlerContext接口的幾個重要方法

          ChannelPipeline pipeline();

          返回屬于當前ChannelHandlerContextChannelPipeline

           

          EventExecutor executor();

          EnventExcutor用于調度EventLoop中的event,這個方法返回當前的EventExecutor

           

          一個Handler可以有多個Context

          一個Handler可以被添加到多個ChannelPipeline。這就意味著一個ChannelHandler可以有多個ChannelHandlerContext

           

           

          ChannelHandler接口

           1 package io.netty.channel;
           2  
           3 import io.netty.channel.group.ChannelGroup; 
           4 import java.lang.annotation.Documented;
           5 import java.lang.annotation.ElementType;
           6 import java.lang.annotation.Inherited;
           7 import java.lang.annotation.Retention;
           8 import java.lang.annotation.RetentionPolicy;
           9 import java.lang.annotation.Target;
          10 import java.nio.channels.Channels;
          11  
          12 public interface ChannelHandler {
          13     void beforeAdd(ChannelHandlerContext ctx) throws Exception;
          14     void afterAdd(ChannelHandlerContext ctx) throws Exception;
          15     void beforeRemove(ChannelHandlerContext ctx) throws Exception;
          16     void afterRemove(ChannelHandlerContext ctx) throws Exception;
          17     void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
          18     void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
          19     @Inherited
          20     @Documented
          21     @Target(ElementType.TYPE)
          22     @Retention(RetentionPolicy.RUNTIME)
          23     @interface Sharable {
          24         // no value
          25     }
          26 }


           

          ChannelHandlerUML

           

          ChannelHandler中的幾個重要方法

          ChannelHandler有兩個子接口,ChannelUpstreamHandlerChannelDownstreamHandler

          1.    ChannelUpstreamHandler用于處理和攔截upstream中的ChannelEvent

          2.    ChannelDownstreamHandler用于處理和攔截downstream中的ChannelEvent

           

          狀態信息

          ChannelHandler一般需要存儲一些狀態信息,以下是【官方推薦】的方法,使用成員變量。

          public class DataServerHandler extends SimpleChannelHandler {
               private boolean loggedIn;
               @Override
               public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
                   Channel ch = e.getChannel();
                   Object o = e.getMessage();
                   if (o instanceof LoginMessage) {
                       authenticate((LoginMessage) o);
                       loggedIn = true;
                   } else (o instanceof GetDataMessage) {
                       if (loggedIn) {
                           ch.write(fetchSecret((GetDataMessage) o));
                       } else {
                           fail();
                       }
                   }
               }
               
           }
           
          // Create a new handler instance per channel.
           
          // See ClientBootstrap#setPipelineFactory(ChannelPipelineFactory).
           public class DataServerPipelineFactory implements ChannelPipelineFactory {
               public ChannelPipeline getPipeline() {
                   return Channels.pipeline(new DataServerHandler());
               }
           }

           

           

          或者使用ChannelLocal,代碼如下

          public final class DataServerState {      public static final ChannelLocal<Boolean> loggedIn = new ChannelLocal<>() {          protected Boolean initialValue(Channel channel) {              return false;          }      }      
          }
           @Sharable  public class DataServerHandler extends SimpleChannelHandler {      @Override      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {          Channel ch = e.getChannel();          Object o = e.getMessage();          if (o instanceof LoginMessage) {              authenticate((LoginMessage) o);              DataServerState.loggedIn.set(ch, true);          } else (o instanceof GetDataMessage) {              if (DataServerState.loggedIn.get(ch)) {                  ctx.getChannel().write(fetchSecret((GetDataMessage) o));              } else {                  fail();              }          }      }      
          }

           // Print the remote addresses of the authenticated clients:  ChannelGroup allClientChannels = ;  for (Channel ch: allClientChannels) {      if (DataServerState.loggedIn.get(ch)) {          System.out.println(ch.getRemoteAddress());      }  }


          備注:因為筆者開始寫Netty源碼分析的時候,Netty 4.0還是處于Alpha階段,之后的API可能還會有改動,筆者將會及時更改。使用開源已經有好幾年的時間了,一直沒有時間和精力來具體研究某個開源項目的具體實現,這次是第一次寫開源項目的源碼分析,如果文中有錯誤的地方,歡迎讀者可以留言指出。對于轉載的讀者,請注明文章的出處。 希望和廣大的開發者/開源愛好者進行交流,歡迎大家的留言和討論。


          -----------------------------------------------------
          Silence, the way to avoid many problems;
          Smile, the way to solve many problems;

          posted on 2012-11-25 16:51 Chan Chen 閱讀(12649) 評論(4)  編輯  收藏 所屬分類: Netty

          評論

          # re: Netty 4.0 源碼分析(五):ChannelHandlerContext和ChannelHandler[未登錄] 2012-11-27 11:14 Alex

          來點注釋,怎么全是代碼!  回復  更多評論   

          # re: Netty 4.0 源碼分析(五):ChannelHandlerContext和ChannelHandler 2012-11-27 11:47 Chan Chen

          @Alex
          具體的注釋會在另外一篇文章(io.netty.handler)中提到,到時候會給出鏈接。這個文章只是對ChannelHandler和ChannelHandlerContext的初步印象理解,很淺顯,很多解釋也不到位。  回復  更多評論   

          # re: Netty 4.0 源碼分析(五):ChannelHandlerContext和ChannelHandler[未登錄] 2013-01-22 15:13

          字太小了 看不清  回復  更多評論   

          # re: Netty 4.0 源碼分析(五):ChannelHandlerContext和ChannelHandler 2013-11-18 21:19 字體

          字太小了+1  回復  更多評論   

          主站蜘蛛池模板: 嘉祥县| 南陵县| 洛宁县| 江安县| 石泉县| 宝坻区| 论坛| 新绛县| 科技| 河池市| 上饶县| 鄂伦春自治旗| 遵义市| 沈丘县| 安国市| 汝城县| 广西| 合山市| 达日县| 六安市| 藁城市| 怀宁县| 鹤山市| 会宁县| 安泽县| 开化县| 鄄城县| 长垣县| 河源市| 东平县| 乐平市| 普兰店市| 庐江县| 鄂托克前旗| 博兴县| 满洲里市| 久治县| 苍梧县| 石台县| 基隆市| 嘉义县|