• Netty入门-Channel


    目录

    Channel详解

    Channel的特点

    Channel接口方法

    ChannelOutboundInvoker接口

    AttributeMap接口

    ChannelHandler接口

    ChannelInboundHandler接口

    ChannelOutboundHandler接口

    ChannelHandlerAdapter

    ChannelInboundHandlerAdapor

    ChannelOutboundHandlerAdapter

    适配器的作用

    ChannelPipeline接口

    创建ChannelPipeline

    ChannelHandlerContext接口


    Channel详解

            Channel代表网络socket或能够进行IO操作的组件的连接关系。这些IO操作包括读、写、连接和绑定。Netty中的Channel提供了如下功能:

    • 查询当前Channel的状态。例如,是打开还是已连接状态等。
    • 提供Channel的参数配置。如接收缓冲区大小。
    • 提供支持的IO操作。如读、写连接和绑定
    • 提供ChannelPipeline。ChannelPipelin用于处理所有与Channel关联的IO事件和请求。

    Channel的特点

    1. 所有IO操作都是异步的

    IO调用将立即返回,返回一个ChannelFuture实例。

    2. Channel是分层的

    3. 向下转型以下访问特定于传输的操作

    4. 释放资源

    Channel接口方法

    1. public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable {
    2. ChannelId id();
    3. EventLoop eventLoop();
    4. Channel parent();
    5. ChannelConfig config();
    6. boolean isOpen();
    7. boolean isRegistered();
    8. boolean isActive();
    9. ChannelMetadata metadata();
    10. SocketAddress localAddress();
    11. SocketAddress remoteAddress();
    12. ChannelFuture closeFuture();
    13. boolean isWritable();
    14. long bytesBeforeUnwritable();
    15. long bytesBeforeWritable();
    16. Channel.Unsafe unsafe();
    17. ChannelPipeline pipeline();
    18. ByteBufAllocator alloc();
    19. Channel read();
    20. Channel flush();
    21. public interface Unsafe {
    22. Handle recvBufAllocHandle();
    23. SocketAddress localAddress();
    24. SocketAddress remoteAddress();
    25. void register(EventLoop var1, ChannelPromise var2);
    26. void bind(SocketAddress var1, ChannelPromise var2);
    27. void connect(SocketAddress var1, SocketAddress var2, ChannelPromise var3);
    28. void disconnect(ChannelPromise var1);
    29. void close(ChannelPromise var1);
    30. void closeForcibly();
    31. void deregister(ChannelPromise var1);
    32. void beginRead();
    33. void write(Object var1, ChannelPromise var2);
    34. void flush();
    35. ChannelPromise voidPromise();
    36. ChannelOutboundBuffer outboundBuffer();
    37. }
    38. }
    • id()方法返回全局唯一的ChannelId
    • eventLoop()方法返回分配给该Channel的EventLoop,一个EventLoop就是一个线程,用来处理连接的生命周期中所发生的事件
    • parent()方法返回该Channel的父Channel
    • config()方法返回该Channel的ChannelConfig,其中包含了该Channel的所有配置设置支持热更新
    • pipeline()方法返回该Channel对应的ChannelPipeline
    • alloc方法返回分配给该Channel的ByteBufAllocator,可以用来分配ByteBuf

    ChannelOutboundInvoker接口

    声明了所有出站的网络操作:

    1. package io.netty.channel;
    2. import java.net.SocketAddress;
    3. public interface ChannelOutboundInvoker {
    4. ChannelFuture bind(SocketAddress var1);
    5. ChannelFuture connect(SocketAddress var1);
    6. ChannelFuture connect(SocketAddress var1, SocketAddress var2);
    7. ChannelFuture disconnect();
    8. ChannelFuture close();
    9. ChannelFuture deregister();
    10. ChannelFuture bind(SocketAddress var1, ChannelPromise var2);
    11. ChannelFuture connect(SocketAddress var1, ChannelPromise var2);
    12. ChannelFuture connect(SocketAddress var1, SocketAddress var2, ChannelPromise var3);
    13. ChannelFuture disconnect(ChannelPromise var1);
    14. ChannelFuture close(ChannelPromise var1);
    15. ChannelFuture deregister(ChannelPromise var1);
    16. ChannelOutboundInvoker read();
    17. ChannelFuture write(Object var1);
    18. ChannelFuture write(Object var1, ChannelPromise var2);
    19. ChannelOutboundInvoker flush();
    20. ChannelFuture writeAndFlush(Object var1, ChannelPromise var2);
    21. ChannelFuture writeAndFlush(Object var1);
    22. ChannelPromise newPromise();
    23. ChannelProgressivePromise newProgressivePromise();
    24. ChannelFuture newSucceededFuture();
    25. ChannelFuture newFailedFuture(Throwable var1);
    26. ChannelPromise voidPromise();
    27. }

    ChannelFuture用于获取异步的结果,ChannelPromise是对ChannelFuture的扩展,支持写的操作。ChannelPromise也被称为可写的ChannelFuture。

    AttributeMap接口

    1. package io.netty.util;
    2. public interface AttributeMap {
    3. Attribute attr(AttributeKey var1);
    4. boolean hasAttr(AttributeKey var1);
    5. }

    AttributeMap就是类似于Map的键值对,键就是AttributeKey类型,值是Attribute类型。

    Netty提供了AttributeMap的默认实现类DefaultAttributeMap,与JDK中的ConcurrentHashMap相比,在高并发下DefaultAttributeMap可以更加节省内存。

    1. package io.netty.util;
    2. import io.netty.util.internal.ObjectUtil;
    3. import java.util.Arrays;
    4. import java.util.concurrent.atomic.AtomicReference;
    5. import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
    6. /**
    7. * Default {@link AttributeMap} implementation which not exibit any blocking behaviour on attribute lookup while using a
    8. * copy-on-write approach on the modify path.
      Attributes lookup and remove exibit {@code O(logn)} time worst-case
    9. * complexity, hence {@code attribute::set(null)} is to be preferred to {@code remove}.
    10. */
    11. public class DefaultAttributeMap implements AttributeMap {
    12. private static final AtomicReferenceFieldUpdater ATTRIBUTES_UPDATER =
    13. AtomicReferenceFieldUpdater.newUpdater(DefaultAttributeMap.class, DefaultAttribute[].class, "attributes");
    14. private static final DefaultAttribute[] EMPTY_ATTRIBUTES = new DefaultAttribute[0];
    15. /**
    16. * Similarly to {@code Arrays::binarySearch} it perform a binary search optimized for this use case, in order to
    17. * save polymorphic calls (on comparator side) and unnecessary class checks.
    18. */
    19. private static int searchAttributeByKey(DefaultAttribute[] sortedAttributes, AttributeKey key) {
    20. int low = 0;
    21. int high = sortedAttributes.length - 1;
    22. while (low <= high) {
    23. int mid = low + high >>> 1;
    24. DefaultAttribute midVal = sortedAttributes[mid];
    25. AttributeKey midValKey = midVal.key;
    26. if (midValKey == key) {
    27. return mid;
    28. }
    29. int midValKeyId = midValKey.id();
    30. int keyId = key.id();
    31. assert midValKeyId != keyId;
    32. boolean searchRight = midValKeyId < keyId;
    33. if (searchRight) {
    34. low = mid + 1;
    35. } else {
    36. high = mid - 1;
    37. }
    38. }
    39. return -(low + 1);
    40. }
    41. private static void orderedCopyOnInsert(DefaultAttribute[] sortedSrc, int srcLength, DefaultAttribute[] copy,
    42. DefaultAttribute toInsert) {
    43. // let's walk backward, because as a rule of thumb, toInsert.key.id() tends to be higher for new keys
    44. final int id = toInsert.key.id();
    45. int i;
    46. for (i = srcLength - 1; i >= 0; i--) {
    47. DefaultAttribute attribute = sortedSrc[i];
    48. assert attribute.key.id() != id;
    49. if (attribute.key.id() < id) {
    50. break;
    51. }
    52. copy[i + 1] = sortedSrc[i];
    53. }
    54. copy[i + 1] = toInsert;
    55. final int toCopy = i + 1;
    56. if (toCopy > 0) {
    57. System.arraycopy(sortedSrc, 0, copy, 0, toCopy);
    58. }
    59. }
    60. private volatile DefaultAttribute[] attributes = EMPTY_ATTRIBUTES;
    61. @SuppressWarnings("unchecked")
    62. @Override
    63. public Attribute attr(AttributeKey key) {
    64. ObjectUtil.checkNotNull(key, "key");
    65. DefaultAttribute newAttribute = null;
    66. for (;;) {
    67. final DefaultAttribute[] attributes = this.attributes;
    68. final int index = searchAttributeByKey(attributes, key);
    69. final DefaultAttribute[] newAttributes;
    70. if (index >= 0) {
    71. final DefaultAttribute attribute = attributes[index];
    72. assert attribute.key() == key;
    73. if (!attribute.isRemoved()) {
    74. return attribute;
    75. }
    76. // let's try replace the removed attribute with a new one
    77. if (newAttribute == null) {
    78. newAttribute = new DefaultAttribute(this, key);
    79. }
    80. final int count = attributes.length;
    81. newAttributes = Arrays.copyOf(attributes, count);
    82. newAttributes[index] = newAttribute;
    83. } else {
    84. if (newAttribute == null) {
    85. newAttribute = new DefaultAttribute(this, key);
    86. }
    87. final int count = attributes.length;
    88. newAttributes = new DefaultAttribute[count + 1];
    89. orderedCopyOnInsert(attributes, count, newAttributes, newAttribute);
    90. }
    91. if (ATTRIBUTES_UPDATER.compareAndSet(this, attributes, newAttributes)) {
    92. return newAttribute;
    93. }
    94. }
    95. }
    96. @Override
    97. public boolean hasAttr(AttributeKey key) {
    98. ObjectUtil.checkNotNull(key, "key");
    99. return searchAttributeByKey(attributes, key) >= 0;
    100. }
    101. private void removeAttributeIfMatch(AttributeKey key, DefaultAttribute value) {
    102. for (;;) {
    103. final DefaultAttribute[] attributes = this.attributes;
    104. final int index = searchAttributeByKey(attributes, key);
    105. if (index < 0) {
    106. return;
    107. }
    108. final DefaultAttribute attribute = attributes[index];
    109. assert attribute.key() == key;
    110. if (attribute != value) {
    111. return;
    112. }
    113. final int count = attributes.length;
    114. final int newCount = count - 1;
    115. final DefaultAttribute[] newAttributes =
    116. newCount == 0? EMPTY_ATTRIBUTES : new DefaultAttribute[newCount];
    117. // perform 2 bulk copies
    118. System.arraycopy(attributes, 0, newAttributes, 0, index);
    119. final int remaining = count - index - 1;
    120. if (remaining > 0) {
    121. System.arraycopy(attributes, index + 1, newAttributes, index, remaining);
    122. }
    123. if (ATTRIBUTES_UPDATER.compareAndSet(this, attributes, newAttributes)) {
    124. return;
    125. }
    126. }
    127. }
    128. @SuppressWarnings("serial")
    129. private static final class DefaultAttribute extends AtomicReference implements Attribute {
    130. private static final AtomicReferenceFieldUpdater MAP_UPDATER =
    131. AtomicReferenceFieldUpdater.newUpdater(DefaultAttribute.class,
    132. DefaultAttributeMap.class, "attributeMap");
    133. private static final long serialVersionUID = -2661411462200283011L;
    134. private volatile DefaultAttributeMap attributeMap;
    135. private final AttributeKey key;
    136. DefaultAttribute(DefaultAttributeMap attributeMap, AttributeKey key) {
    137. this.attributeMap = attributeMap;
    138. this.key = key;
    139. }
    140. @Override
    141. public AttributeKey key() {
    142. return key;
    143. }
    144. private boolean isRemoved() {
    145. return attributeMap == null;
    146. }
    147. @Override
    148. public T setIfAbsent(T value) {
    149. while (!compareAndSet(null, value)) {
    150. T old = get();
    151. if (old != null) {
    152. return old;
    153. }
    154. }
    155. return null;
    156. }
    157. @Override
    158. public T getAndRemove() {
    159. final DefaultAttributeMap attributeMap = this.attributeMap;
    160. final boolean removed = attributeMap != null && MAP_UPDATER.compareAndSet(this, attributeMap, null);
    161. T oldValue = getAndSet(null);
    162. if (removed) {
    163. attributeMap.removeAttributeIfMatch(key, this);
    164. }
    165. return oldValue;
    166. }
    167. @Override
    168. public void remove() {
    169. final DefaultAttributeMap attributeMap = this.attributeMap;
    170. final boolean removed = attributeMap != null && MAP_UPDATER.compareAndSet(this, attributeMap, null);
    171. set(null);
    172. if (removed) {
    173. attributeMap.removeAttributeIfMatch(key, this);
    174. }
    175. }
    176. }
    177. }

    ChannelHandler接口

    1. package io.netty.channel;
    2. import io.netty.util.Attribute;
    3. import io.netty.util.AttributeKey;
    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. public interface ChannelHandler {
    11. /**
    12. * Gets called after the {@link ChannelHandler} was added to the actual context and it's ready to handle events.
    13. */
    14. void handlerAdded(ChannelHandlerContext ctx) throws Exception;
    15. /**
    16. * Gets called after the {@link ChannelHandler} was removed from the actual context and it doesn't handle events
    17. * anymore.
    18. */
    19. void handlerRemoved(ChannelHandlerContext ctx) throws Exception;
    20. /**
    21. * Gets called if a {@link Throwable} was thrown.
    22. *
    23. * @deprecated if you want to handle this event you should implement {@link ChannelInboundHandler} and
    24. * implement the method there.
    25. */
    26. @Deprecated
    27. void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
    28. /**
    29. * Indicates that the same instance of the annotated {@link ChannelHandler}
    30. * can be added to one or more {@link ChannelPipeline}s multiple times
    31. * without a race condition.
    32. *

    33. * If this annotation is not specified, you have to create a new handler
    34. * instance every time you add it to a pipeline because it has unshared
    35. * state such as member variables.
    36. *

    37. * This annotation is provided for documentation purpose, just like
    38. */
    39. @Inherited
    40. @Documented
    41. @Target(ElementType.TYPE)
    42. @Retention(RetentionPolicy.RUNTIME)
    43. @interface Sharable {
    44. // no value
    45. }
    46. }


     Handles an I/O event or intercepts an I/O operation, and forwards it to its next handler in
     its ChannelPipeline

    ChannelHandler本身没有提供什么方法,可以使用其子类:

    • ChannelInboundHandler:处理入站IO事件
    • ChannelOutboundHandler:处理出站IO事件
    • ChannelHandlerAdapter:采用适配器模式的ChannelHandler适配器

    ChannelInboundHandler接口

    1. package io.netty.channel;
    2. /**
    3. * {@link ChannelHandler} which adds callbacks for state changes. This allows the user
    4. * to hook in to state changes easily.
    5. */
    6. public interface ChannelInboundHandler extends ChannelHandler {
    7. /**
    8. * The {@link Channel} of the {@link ChannelHandlerContext} was registered with its {@link EventLoop}
    9. */
    10. void channelRegistered(ChannelHandlerContext ctx) throws Exception;
    11. /**
    12. * The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop}
    13. */
    14. void channelUnregistered(ChannelHandlerContext ctx) throws Exception;
    15. /**
    16. * The {@link Channel} of the {@link ChannelHandlerContext} is now active
    17. */
    18. void channelActive(ChannelHandlerContext ctx) throws Exception;
    19. /**
    20. * The {@link Channel} of the {@link ChannelHandlerContext} was registered is now inactive and reached its
    21. * end of lifetime.
    22. */
    23. void channelInactive(ChannelHandlerContext ctx) throws Exception;
    24. /**
    25. * Invoked when the current {@link Channel} has read a message from the peer.
    26. */
    27. void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;
    28. /**
    29. * Invoked when the last message read by the current read operation has been consumed by
    30. * {@link #channelRead(ChannelHandlerContext, Object)}. If {@link ChannelOption#AUTO_READ} is off, no further
    31. * attempt to read an inbound data from the current {@link Channel} will be made until
    32. * {@link ChannelHandlerContext#read()} is called.
    33. */
    34. void channelReadComplete(ChannelHandlerContext ctx) throws Exception;
    35. /**
    36. * Gets called if an user event was triggered.
    37. */
    38. void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
    39. /**
    40. * Gets called once the writable state of a {@link Channel} changed. You can check the state with
    41. * {@link Channel#isWritable()}.
    42. */
    43. void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception;
    44. /**
    45. * Gets called if a {@link Throwable} was thrown.
    46. */
    47. @Override
    48. @SuppressWarnings("deprecation")
    49. void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
    50. }

    ChannelOutboundHandler接口

    1. package io.netty.channel;
    2. import java.net.SocketAddress;
    3. public interface ChannelOutboundHandler extends ChannelHandler {
    4. /**
    5. * Called once a bind operation is made.
    6. *
    7. * @param ctx the {@link ChannelHandlerContext} for which the bind operation is made
    8. * @param localAddress the {@link SocketAddress} to which it should bound
    9. * @param promise the {@link ChannelPromise} to notify once the operation completes
    10. * @throws Exception thrown if an error occurs
    11. */
    12. void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception;
    13. /**
    14. * Called once a connect operation is made.
    15. *
    16. * @param ctx the {@link ChannelHandlerContext} for which the connect operation is made
    17. * @param remoteAddress the {@link SocketAddress} to which it should connect
    18. * @param localAddress the {@link SocketAddress} which is used as source on connect
    19. * @param promise the {@link ChannelPromise} to notify once the operation completes
    20. * @throws Exception thrown if an error occurs
    21. */
    22. void connect(
    23. ChannelHandlerContext ctx, SocketAddress remoteAddress,
    24. SocketAddress localAddress, ChannelPromise promise) throws Exception;
    25. /**
    26. * Called once a disconnect operation is made.
    27. *
    28. * @param ctx the {@link ChannelHandlerContext} for which the disconnect operation is made
    29. * @param promise the {@link ChannelPromise} to notify once the operation completes
    30. * @throws Exception thrown if an error occurs
    31. */
    32. void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
    33. /**
    34. * Called once a close operation is made.
    35. *
    36. * @param ctx the {@link ChannelHandlerContext} for which the close operation is made
    37. * @param promise the {@link ChannelPromise} to notify once the operation completes
    38. * @throws Exception thrown if an error occurs
    39. */
    40. void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
    41. /**
    42. * Called once a deregister operation is made from the current registered {@link EventLoop}.
    43. *
    44. * @param ctx the {@link ChannelHandlerContext} for which the close operation is made
    45. * @param promise the {@link ChannelPromise} to notify once the operation completes
    46. * @throws Exception thrown if an error occurs
    47. */
    48. void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
    49. /**
    50. * Intercepts {@link ChannelHandlerContext#read()}.
    51. */
    52. void read(ChannelHandlerContext ctx) throws Exception;
    53. /**
    54. * Called once a write operation is made. The write operation will write the messages through the
    55. * {@link ChannelPipeline}. Those are then ready to be flushed to the actual {@link Channel} once
    56. * {@link Channel#flush()} is called
    57. *
    58. * @param ctx the {@link ChannelHandlerContext} for which the write operation is made
    59. * @param msg the message to write
    60. * @param promise the {@link ChannelPromise} to notify once the operation completes
    61. * @throws Exception thrown if an error occurs
    62. */
    63. void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception;
    64. /**
    65. * Called once a flush operation is made. The flush operation will try to flush out all previous written messages
    66. * that are pending.
    67. *
    68. * @param ctx the {@link ChannelHandlerContext} for which the flush operation is made
    69. * @throws Exception thrown if an error occurs
    70. */
    71. void flush(ChannelHandlerContext ctx) throws Exception;
    72. }

    ChannelHandlerAdapter

    1. package io.netty.channel;
    2. import io.netty.channel.ChannelHandler.Sharable;
    3. import io.netty.channel.ChannelHandlerMask.Skip;
    4. import io.netty.util.internal.InternalThreadLocalMap;
    5. import java.util.Map;
    6. public abstract class ChannelHandlerAdapter implements ChannelHandler {
    7. boolean added;
    8. public ChannelHandlerAdapter() {
    9. }
    10. protected void ensureNotSharable() {
    11. if (this.isSharable()) {
    12. throw new IllegalStateException("ChannelHandler " + this.getClass().getName() + " is not allowed to be shared");
    13. }
    14. }
    15. public boolean isSharable() {
    16. Class clazz = this.getClass();
    17. Map, Boolean> cache = InternalThreadLocalMap.get().handlerSharableCache();
    18. Boolean sharable = (Boolean)cache.get(clazz);
    19. if (sharable == null) {
    20. sharable = clazz.isAnnotationPresent(Sharable.class);
    21. cache.put(clazz, sharable);
    22. }
    23. return sharable;
    24. }
    25. public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
    26. }
    27. public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
    28. }
    29. /** @deprecated */
    30. @Skip
    31. @Deprecated
    32. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    33. ctx.fireExceptionCaught(cause);
    34. }
    35. }

    ChannelHandlerAdaptor常用的两个子类,分别是ChannelInboundHandlerAdapor、ChannelOutboundHandlerAdatper

    ChannelInboundHandlerAdapor

    1. package io.netty.channel;
    2. import io.netty.channel.ChannelHandlerMask.Skip;
    3. public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {
    4. public ChannelInboundHandlerAdapter() {
    5. }
    6. @Skip
    7. public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
    8. ctx.fireChannelRegistered();
    9. }
    10. @Skip
    11. public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
    12. ctx.fireChannelUnregistered();
    13. }
    14. @Skip
    15. public void channelActive(ChannelHandlerContext ctx) throws Exception {
    16. ctx.fireChannelActive();
    17. }
    18. @Skip
    19. public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    20. ctx.fireChannelInactive();
    21. }
    22. @Skip
    23. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    24. ctx.fireChannelRead(msg);
    25. }
    26. @Skip
    27. public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
    28. ctx.fireChannelReadComplete();
    29. }
    30. @Skip
    31. public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
    32. ctx.fireUserEventTriggered(evt);
    33. }
    34. @Skip
    35. public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
    36. ctx.fireChannelWritabilityChanged();
    37. }
    38. @Skip
    39. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    40. ctx.fireExceptionCaught(cause);
    41. }
    42. }

    ChannelOutboundHandlerAdapter

    1. package io.netty.channel;
    2. import io.netty.channel.ChannelHandlerMask.Skip;
    3. import java.net.SocketAddress;
    4. public class ChannelOutboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelOutboundHandler {
    5. public ChannelOutboundHandlerAdapter() {
    6. }
    7. @Skip
    8. public void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception {
    9. ctx.bind(localAddress, promise);
    10. }
    11. @Skip
    12. public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
    13. ctx.connect(remoteAddress, localAddress, promise);
    14. }
    15. @Skip
    16. public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    17. ctx.disconnect(promise);
    18. }
    19. @Skip
    20. public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    21. ctx.close(promise);
    22. }
    23. @Skip
    24. public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
    25. ctx.deregister(promise);
    26. }
    27. @Skip
    28. public void read(ChannelHandlerContext ctx) throws Exception {
    29. ctx.read();
    30. }
    31. @Skip
    32. public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
    33. ctx.write(msg, promise);
    34. }
    35. @Skip
    36. public void flush(ChannelHandlerContext ctx) throws Exception {
    37. ctx.flush();
    38. }
    39. }

    适配器的作用

    使用适配器是因为适配器的子类不需要实现父类中的所有方法,按需覆盖适配器的方法即可。

    ChannelPipeline接口

    ChannelPipeline接口设计采用了责任链模式,底层采用双向链表的数据结构,将链上个各个处理器串联起来。

    1. * I/O Request
    2. * via {@link Channel} or
    3. * {@link ChannelHandlerContext}
    4. * |
    5. * +---------------------------------------------------+---------------+
    6. * | ChannelPipeline | |
    7. * | \|/ |
    8. * | +---------------------+ +-----------+----------+ |
    9. * | | Inbound Handler N | | Outbound Handler 1 | |
    10. * | +----------+----------+ +-----------+----------+ |
    11. * | /|\ | |
    12. * | | \|/ |
    13. * | +----------+----------+ +-----------+----------+ |
    14. * | | Inbound Handler N-1 | | Outbound Handler 2 | |
    15. * | +----------+----------+ +-----------+----------+ |
    16. * | /|\ . |
    17. * | . . |
    18. * | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
    19. * | [ method call] [method call] |
    20. * | . . |
    21. * | . \|/ |
    22. * | +----------+----------+ +-----------+----------+ |
    23. * | | Inbound Handler 2 | | Outbound Handler M-1 | |
    24. * | +----------+----------+ +-----------+----------+ |
    25. * | /|\ | |
    26. * | | \|/ |
    27. * | +----------+----------+ +-----------+----------+ |
    28. * | | Inbound Handler 1 | | Outbound Handler M | |
    29. * | +----------+----------+ +-----------+----------+ |
    30. * | /|\ | |
    31. * +---------------+-----------------------------------+---------------+
    32. * | \|/
    33. * +---------------+-----------------------------------+---------------+
    34. * | | | |
    35. * | [ Socket.read() ] [ Socket.write() ] |
    36. * | |
    37. * | Netty Internal I/O Threads (Transport Implementation) |
    38. * +-------------------------------------------------------------------+
    1. public interface ChannelPipeline
    2. extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable> {
    3. ChannelPipeline addFirst(String name, ChannelHandler handler);
    4. ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
    5. ChannelPipeline addLast(String name, ChannelHandler handler);
    6. ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
    7. ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
    8. ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
    9. ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
    10. ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
    11. ChannelPipeline addFirst(ChannelHandler... handlers);
    12. ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
    13. ChannelPipeline addLast(ChannelHandler... handlers);
    14. ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
    15. ChannelPipeline remove(ChannelHandler handler);
    16. ChannelHandler remove(String name);
    17. extends ChannelHandler> T remove(Class handlerType);
    18. ChannelHandler removeFirst();
    19. ChannelHandler removeLast();
    20. ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
    21. ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
    22. extends ChannelHandler> T replace(Class oldHandlerType, String newName,
    23. ChannelHandler newHandler);
    24. ChannelHandler first();
    25. ChannelHandlerContext firstContext();
    26. ChannelHandler last();
    27. ChannelHandlerContext lastContext();
    28. ChannelHandler get(String name);
    29. extends ChannelHandler> T get(Class handlerType);
    30. ChannelHandlerContext context(ChannelHandler handler);
    31. ChannelHandlerContext context(String name);
    32. ChannelHandlerContext context(Class handlerType);
    33. Channel channel();
    34. List names();
    35. Map toMap();
    36. @Override
    37. ChannelPipeline fireChannelRegistered();
    38. @Override
    39. ChannelPipeline fireChannelUnregistered();
    40. @Override
    41. ChannelPipeline fireChannelActive();
    42. @Override
    43. ChannelPipeline fireChannelInactive();
    44. @Override
    45. ChannelPipeline fireExceptionCaught(Throwable cause);
    46. @Override
    47. ChannelPipeline fireUserEventTriggered(Object event);
    48. @Override
    49. ChannelPipeline fireChannelRead(Object msg);
    50. @Override
    51. ChannelPipeline fireChannelReadComplete();
    52. @Override
    53. ChannelPipeline fireChannelWritabilityChanged();
    54. @Override
    55. ChannelPipeline flush();
    56. }

    创建ChannelPipeline

    ChannelPipeline数据管道是与Channel通道绑定的,一个Channel通道对应一个ChannelPipeline,ChannelPipeline是在Channel初始化时被创建的。

    ChannelHandlerContext接口

    ChannelHandlerContext接口是联系ChannelHandler与其ChannelPipeline之间的纽带。

    每当有ChannelHandler添加到ChannelPipeline中时,都会常见ChannelHandlerContext。ChannelHandlerContext的主要功能是管理它所关联的ChannelHandler和在同一个ChannelPipeline中的其他ChannelHandler之间的交互。例如,ChannelHandlerContext可以通知ChannelPipeline中的下一个ChannelHandler开始执行及动态修改其所属的ChannelPipeline。

  • 相关阅读:
    苹果平板可以用别的电容笔吗?电容笔和Apple pencil区别
    用友GRP-U8 SQL注入漏洞复现
    【最新版配置conda环境】新版pycharm导入新版anaconda环境
    kafka系列七、kafka核心配置(转)
    一小时极速掌握HybridCLR热更新
    绝地求生:想玩以前的老地图
    MD中 面料的物理属性参数
    keras实现深度神经网络,keras实现卷积神经网络
    python使用SMTP发送邮件
    什么是Rebex Total Pack for.NET?
  • 原文地址:https://blog.csdn.net/lovelovelovelovelo/article/details/127724712