Netty学习:ChannelHandlerContext及基实现类AbstractChannelHandlerContext

 ChannelHandlerContext

允许{@link ChannelHandler}与其{@link ChannelPipeline}和其他处理程序交互。处理程序可以通知{@link ChannelPipeline}中的下一个{@link ChannelHandler},还可以动态修改它所属的{@link ChannelPipeline}。

通知

通过调用这里提供的各种方法之一,您可以在同一个{@link ChannelPipeline}中通知最近的处理程序。请参考{@link ChannelPipeline}了解事件是如何流动的。

修改pipeline

您可以通过调用{@link #pipeline()}来获得处理程序所属的{@link ChannelPipeline}。一个重要的应用程序可以在运行时动态地在管道中插入、删除或替换处理程序。

检索以便以后使用

您可以保留{@link ChannelHandlerContext}供以后使用,例如在处理程序方法之外触发事件,甚至从不同的线程触发事件。

 * public class MyHandler extends {@link ChannelDuplexHandler} {
 *
 *     <b>private {@link ChannelHandlerContext} ctx;</b>
 *
 *     public void beforeAdd({@link ChannelHandlerContext} ctx) {
 *         <b>this.ctx = ctx;</b>
 *     }
 *
 *     public void login(String username, password) {
 *         ctx.write(new LoginMessage(username, password));
 *     }
 *     ...
 * }

存储状态信息

{@link #attr(AttributeKey)}允许存储和访问与处理程序及其上下文相关的有状态信息。请参考{@link ChannelHandler}了解各种管理有状态信息的推荐方法。

A handler可以有多个上下文

请注意,{@link ChannelHandler}实例可以添加到多个{@link ChannelPipeline}。这意味着单个{@link ChannelHandler}实例可以有多个{@link ChannelHandlerContext},因此,如果将单个实例多次添加到一个或多个{@link ChannelPipeline},则可以使用不同的{@link ChannelHandlerContext}调用该实例。

例如,下面的处理程序将拥有与添加到管道的次数相同的独立{@link AttributeKey}s,不管它是多次添加到同一管道还是多次添加到不同管道:

* public class FactorialHandler extends {@link ChannelInboundHandlerAdapter} {
 *
 *   private final {@link AttributeKey}&lt;{@link Integer}&gt; counter = {@link AttributeKey}.valueOf("counter");
 *
 *   // This handler will receive a sequence of increasing integers starting
 *   // from 1.
 *   {@code @Override}
 *   public void channelRead({@link ChannelHandlerContext} ctx, Object msg) {
 *     Integer a = ctx.attr(counter).get();
 *
 *     if (a == null) {
 *       a = 1;
 *     }
 *
 *     attr.set(a * (Integer) msg);
 *   }
 * }

不同的上下文对象被赋予“f1”、“f2”、“f3”和“f4”,即使它们引用相同的处理程序实例。因为因数处理程序将其状态存储在上下文对象中(使用{@link AttributeKey}),所以一旦两个管道(p1和p2)处于活动状态,就可以正确计算4次阶乘。

 * FactorialHandler fh = new FactorialHandler();
 *
 * {@link ChannelPipeline} p1 = {@link Channels}.pipeline();
 * p1.addLast("f1", fh);
 * p1.addLast("f2", fh);
 *
 * {@link ChannelPipeline} p2 = {@link Channels}.pipeline();
 * p2.addLast("f3", fh);
 * p2.addLast("f4", fh);

其他值得阅读的资源

请参考{@link ChannelHandler}和{@link ChannelPipeline}来了解更多关于入站和出站操作的信息,它们之间的基本区别是什么,它们如何在管道中流动,以及如何在应用程序中处理操作。

参考 :

Netty学习:ChannelInboundInvoker

Netty学习:ChannelOutboundInvoker

猜你喜欢

转载自blog.csdn.net/AnY11/article/details/84944852