diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandler.java b/src/main/java/org/jboss/netty/channel/ChannelHandler.java index 76b2083d22..f7f81a04e2 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandler.java @@ -50,7 +50,7 @@ import org.jboss.netty.channel.group.ChannelGroup; * object. A {@link ChannelHandler} is supposed to interact with the * {@link ChannelPipeline} it belongs to via a context object. Using the * context object, the {@link ChannelHandler} can pass events upstream or - * downstream, modify the behavior of the pipeline, or store the information + * downstream, modify the pipeline dynamically, or store the information * (attachment) which is specific to the handler. * *

State management

diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java index e5bd801782..5e9a41a4b6 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java @@ -17,23 +17,58 @@ package org.jboss.netty.channel; /** - * Provides the properties and operations which are specific to a - * {@link ChannelHandler} and the {@link ChannelPipeline} it belongs to. - * Via a {@link ChannelHandlerContext}, a {@link ChannelHandler} can send - * a {@link ChannelEvent} upstream or downstream, modify the behavior of the - * pipeline, or store the information (attachment) which is specific to the - * handler. - *
- *         n = the number of the handler entries in a pipeline
+ * Enables a {@link ChannelHandler} to send a {@link ChannelEvent} upstream or
+ * downstream, modify a {@link ChannelPipeline} dynamically, or store stateful
+ * information.
  *
- * +---------+ 1 .. 1 +----------+ 1    n +---------+ n    m +---------+
- * | Channel |--------| Pipeline |--------| Context |--------| Handler |
- * +---------+        +----------+        +----+----+        +----+----+
- *                                             | 1..1             |
- *                                       +-----+------+           |
- *                                       | Attachment |<----------+
- *                                       +------------+    stores
+ * 

Sending an event

+ * + * You can send or forward a {@link ChannelEvent} to the closest handler in the + * same {@link ChannelPipeline} by calling {@link #sendUpstream(ChannelEvent)} + * or {@link #sendDownstream(ChannelEvent)}. Please refer to + * {@link ChannelPipeline} to understand how an event flows. + * + *

Modifying a pipeline

+ * + * You can get the {@link ChannelPipeline} your handler belongs to by calling + * {@link #getPipeline()}. A non-trivial application could insert, remove, or + * replace handlers in the pipeline dynamically in runtime. + * + *

Storing stateful information

+ * + * {@link #setAttachment(Object)} and {@link #getAttachment()} allow you to + * store and access stateful information that is related with a handler and its + * context. Please refer to {@link ChannelHandler} to learn various recommended + * ways to manage stateful information. + * + *

Retrieving for later use

+ * + * You can keep the {@link ChannelHandlerContext} for later use, such as + * triggering an event outside the handler methods, even from a different thread. + *
+ * public class MyHandler extends {@link SimpleChannelHandler}
+ *                        implements {@link LifeCycleAwareChannelHandler} {
+ *
+ *     private {@link ChannelHandlerContext} ctx;
+ *
+ *     public void beforeAdd({@link ChannelHandlerContext} ctx) {
+ *         this.ctx = ctx;
+ *     }
+ *
+ *     {@code @Override}
+ *     public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} evt) {
+ *         ctx.setAttachment(evt.getMessage());
+ *     }
+ *
+ *     public Object getLastReceivedMessage() {
+ *         return ctx.getAttachment();
+ *     }
+ *     ...
+ * }
  * 
+ * + *

A handler can have more than one context

+ * * Please note that a {@link ChannelHandler} instance can be added to more than * one {@link ChannelPipeline}. It means a single {@link ChannelHandler} * instance can have more than one {@link ChannelHandlerContext} and therefore @@ -77,32 +112,6 @@ package org.jboss.netty.channel; * p2.addLast("f4", fh); *
* - *

Retrieving for later use

- * - * You can keep the {@link ChannelHandlerContext} for later use, such as - * triggering an event outside the handler methods, even from a different thread. - *
- * public class MyHandler extends {@link SimpleChannelHandler}
- *                        implements {@link LifeCycleAwareChannelHandler} {
- *
- *     private {@link ChannelHandlerContext} ctx;
- *
- *     public void beforeAdd({@link ChannelHandlerContext} ctx) {
- *         this.ctx = ctx;
- *     }
- *
- *     {@code @Override}
- *     public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} evt) {
- *         ctx.setAttachment(evt.getMessage());
- *     }
- *
- *     public Object getLastReceivedMessage() {
- *         return ctx.getAttachment();
- *     }
- *     ...
- * }
- * 
- * *

Additional resources worth reading

*

* Please refer to the {@link ChannelHandler}, {@link ChannelEvent}, and diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java index cdc74e73b8..66bf314338 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java @@ -36,7 +36,11 @@ import org.jboss.netty.handler.ssl.SslHandler; * *

Creation of a pipeline

*

- * It is recommended to create a new pipeline using the helper methods in + * For each new channel, a new pipeline must be created. If a new pipeline is + * attached to a channel, the coupling is permanent; the channel cannot attach + * another pipeline to it nor detach the current pipeline from it. + *

+ * The recommended way to create a new pipeline is to use the helper methods in * {@link Channels} rather than calling an individual implementation's * constructor: *