Netty3 源码分析 - AbstractChannel

Netty3 源码分析 - AbstractChannel


AbstractChannel 是Channel的部分实现,维护了一个通道相关的资源,如channel id, pipeline等;而且实现了对该套接字的IO操作,以及设置interestOps;这里还没有牵扯到底层的细节,只是这个框架的结构。(Channels中的具体实现有待分析)

源码能说明一切:
/**
 * A skeletal Channel implementation.
 */
public   abstract  class  AbstractChannel  implements
          org.jboss.netty.channel.Channel {

       static   final  ConcurrentMap<Integer, Channel>  allChannels   new  ConcurrentHashMap<Integer, Channel>();

       private   static   final  Random  random  =  new  Random();

       private   static  Integer allocateId(Channel channel) {
          Integer id =  random  .nextInt();
            for  (;;) {
                // 循环直到得到一个唯一的ID.
                // It should be found in one loop practically.
                if  ( allChannels  .putIfAbsent(id, channel) ==  null  ) {
                     // Successfully acquired.
                     return  id;
              }  else  {
                     // Taken by other channel at almost the same moment.
                   id = id.intValue() + 1;
              }
          }
     }

       private   final  Integer  id  ;
       private   final  Channel  parent  //
       private   final  ChannelFactory  factory  ;
       private   final  ChannelPipeline  pipeline  ;
       //
       private   final  ChannelFuture  succeededFuture  new  SucceededChannelFuture(
                this  );
       private   final  ChannelCloseFuture  closeFuture  new  ChannelCloseFuture();
       private volatile int interestOps OP_READ;

       /** Cache for the string representation of this channel */
       private   boolean   strValConnected  ;
       private  String  strVal ;
       private   volatile  Object  attachment  ;

       /**
      * 创建实例,注意各个参数的含义,特别是ChannelSink
      *
      *  @param  parent
      *            the parent of this channel. {@code null} if there's no parent.
      *  @param  factory
      *            the factory which created this channel
      *  @param  pipeline
      *            the pipeline which is going to be attached to this channel
      *  @param  sink
      *            the sink which will receive downstream events from the
      *            pipeline and send upstream events to the pipeline
      */
       protected  AbstractChannel(Channel parent, ChannelFactory factory,
              ChannelPipeline pipeline, ChannelSink sink) {

            this  . parent  = parent;
            this  . factory  = factory;
            this  . pipeline  = pipeline;

            id  = allocateId(  this );

          pipeline.attach(  this  , sink);
     }

       // (Internal use only) Creates a new temporary instance with the specified
       // ID.
       protected  AbstractChannel(Integer id, Channel parent,
              ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink) {

            this  . id  = id;
            this  . parent  = parent;
            this  . factory  = factory;
            this  . pipeline  = pipeline;
          pipeline.attach(  this  , sink);
     }

       public   final  Integer getId() {
            return   id  ;
     }

       public  Channel getParent() {
            return   parent  ;
     }

       public  ChannelFactory getFactory() {
            return   factory  ;
     }

       public  ChannelPipeline getPipeline() {
            return   pipeline  ;
     }

       /**
      * Returns the cached SucceededChannelFuture instance.
      */
       protected  ChannelFuture getSucceededFuture() {
            return   succeededFuture  ;
     }

       /**
      * Returns the FailedChannelFuture whose cause is an
      * UnsupportedOperationException.
      */
       protected  ChannelFuture getUnsupportedOperationFuture() {
            return   new  FailedChannelFuture(  this ,
                     new  UnsupportedOperationException());
     }

       /**
      * Returns the ID of this channel.
      */
       @Override
       public   final   int  hashCode() {
            return   id  ;
     }

       // 引用相等
       @Override
       public   final   boolean  equals(Object o) {
            return   this  == o;
     }

       // 用ID来比较
       public   final   int  compareTo(Channel o) {
            return  getId().compareTo(o.getId());
     }

       public   boolean  isOpen() {
            return  ! closeFuture  .isDone();
     }

       /**
      * Marks this channel as closed. This method is intended to be called by an
      * internal component  -  please do not call it unless you know what you are
      * doing.
      *
      *  @return  {@code true} if and only if this channel was not marked as closed
      *         yet
      */
       protected   boolean  setClosed() {
            // Deallocate the current channel's ID from allChannels so that other
            // new channels can use it.
            allChannels  .remove( id  );

            return   closeFuture  .setClosed();
     }

       // 下面都是调用辅助函数来完成套接字的基本操作逻辑
       public  ChannelFuture bind(SocketAddress localAddress) {
            return  Channels.bind(  this  , localAddress);
     }

       public  ChannelFuture unbind() {
            return  Channels.unbind(  this  );
     }

       public  ChannelFuture close() {
          ChannelFuture returnedCloseFuture = Channels.close(  this );
            assert   closeFuture  == returnedCloseFuture;
            return   closeFuture  ;
     }

       public  ChannelFuture getCloseFuture() {
            return   closeFuture  ;
     }

       public  ChannelFuture connect(SocketAddress remoteAddress) {
            return  Channels.connect(  this  , remoteAddress);
     }

       public  ChannelFuture disconnect() {
            return  Channels.disconnect(  this  );
     }

       public   int  getInterestOps() {
            return   interestOps  ;
     }

       public  ChannelFuture setInterestOps(  int  interestOps) {
            return  Channels.setInterestOps(  this  , interestOps);
     }

       /**
      * Sets the interestOps property of this channel immediately. This method is
      * intended to be called by an internal component  -  please do not call it
      * unless you know what you are doing. 直接改变的成员变量,而不是通过发送请求码到最后一个handler
      */
       protected   void  setInterestOpsNow(  int  interestOps) {
            this  . interestOps  = interestOps;
     }

       public   boolean  isReadable() {
            return  (getInterestOps() &  OP_READ ) != 0;
     }

       public   boolean  isWritable() {
            return  (getInterestOps() &  OP_WRITE ) == 0;
     }

       public  ChannelFuture setReadable(  boolean  readable) {
            if  (readable) {
                return  setInterestOps(getInterestOps() |  OP_READ  );
          }  else  {
                return  setInterestOps(getInterestOps() & ~ OP_READ  );
          }
     }

       public  ChannelFuture write(Object message) {
            return  Channels.write(  this  , message);
     }

       public  ChannelFuture write(Object message, SocketAddress remoteAddress) {
            return  Channels.write(  this  , message, remoteAddress);
     }

       public  Object getAttachment() {
            return   attachment  ;
     }

       public   void  setAttachment(Object attachment) {
            this  . attachment  = attachment;
     }

       /**
      * Returns the String representation of this channel. The returned string
      * contains the ID, local address, and remote address of this channel for
      * easier identification.
      */
       @Override
       public  String toString() {
            boolean  connected = isConnected();
            if  ( strValConnected  == connected &&  strVal  !=  null  ) {
                return   strVal  ;
          }

          StringBuilder buf =  new  StringBuilder(128);
          buf.append(  "[id: 0x"  );
          buf.append(getIdString());

          SocketAddress localAddress = getLocalAddress();
          SocketAddress remoteAddress = getRemoteAddress();
            if  (remoteAddress !=  null ) {
              buf.append(  ", "  );
                if  (getParent() ==  null ) {
                   buf.append(localAddress);
                   buf.append(connected ?  " => "   " :> " );
                   buf.append(remoteAddress);
              }  else  {
                   buf.append(remoteAddress);
                   buf.append(connected ?  " => "   " :> " );
                   buf.append(localAddress);
              }
          }  else   if  (localAddress !=  null ) {
              buf.append(  ", "  );
              buf.append(localAddress);
          }

          buf.append(  ']' );

          String strVal = buf.toString();
            this  . strVal  = strVal;
            strValConnected  = connected;
            return  strVal;
     }

       private  String getIdString() {
          String answer = Integer.toHexString(  id .intValue());
            switch  (answer.length()) {
            case  0:
              answer =  "00000000"  ;
                break  ;
            case  1:
              answer =  "0000000"  + answer;
                break  ;
            case  2:
              answer =  "000000"  + answer;
                break  ;
            case  3:
              answer =  "00000"  + answer;
                break  ;
            case  4:
              answer =  "0000"  + answer;
                break  ;
            case  5:
              answer =  "000"  + answer;
                break  ;
            case  6:
              answer =  "00"  + answer;
                break  ;
            case  7:
              answer =  '0'  + answer;
                break  ;
          }
            return  answer;
     }

       private   final   class  ChannelCloseFuture  extends  DefaultChannelFuture {

            public  ChannelCloseFuture() {
                super  (AbstractChannel.  this false );
          }

            @Override
            public   boolean  setSuccess() {
                // User is not supposed to call this method - ignore silently.
                return   false  ;
          }

            @Override
            public   boolean  setFailure(Throwable cause) {
                // User is not supposed to call this method - ignore silently.
                return   false  ;
          }

            boolean  setClosed() {
                return   super  .setSuccess();
          }
     }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值