Netty3 源码分析 - AbstractChannel

来源:互联网 发布:淘宝美工招聘网 编辑:程序博客网 时间:2024/05/22 07:00
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. thisfalse);
          }

           @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
原创粉丝点击