diff --git a/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java b/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java index 23f97dcc74..67541b14d1 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java @@ -15,71 +15,20 @@ */ package org.jboss.netty.channel; -import java.net.SocketAddress; - - /** * Handles or intercepts a downstream {@link ChannelEvent}, and sends a * {@link ChannelEvent} to the next handler in a {@link ChannelPipeline}. - * - *
- * A downstream event is an event which is supposed to be processed by - * a series of downstream handlers in the {@link ChannelPipeline}. It is often - * an I/O request made by a user application. *
* The most common use case of this interface is to intercept an I/O request - * such as {@link Channel#write(Object)} and {@link Channel#close()}. The - * received {@link ChannelEvent} object is interpreted as described in the - * following table: + * such as {@link Channel#write(Object)} and {@link Channel#close()}. * - *
Event name | Event type and condition | Meaning | - *
---|---|---|
{@code "write"} | - *{@link MessageEvent} | Send a message to the {@link Channel}. | - *
{@code "bind"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress}) |
- * Bind the {@link Channel} to the specified local address. | - *
{@code "unbind"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@code null}) |
- * Unbind the {@link Channel} from the current local address. | - *
{@code "connect"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) |
- * Connect the {@link Channel} to the specified remote address. | - *
{@code "disconnect"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@code null}) |
- * Disconnect the {@link Channel} from the current remote address. | - *
{@code "close"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code false}) |
- * Close the {@link Channel}. | - *
- * Other event types and conditions which were not addressed here will be - * ignored and discarded. Please note that there's no {@code "open"} in the - * table. It is because a {@link Channel} is always open when it is created - * by a {@link ChannelFactory}. - * - *
- * You might want to refer to {@link ChannelUpstreamHandler} to see how a - * {@link ChannelEvent} is interpreted when going upstream. Also, please refer - * to the {@link ChannelEvent} and {@link ChannelPipeline} documentation to find - * out what an upstream event and a downstream event are, what fundamental - * differences they have, and how they flow in a pipeline. + * In most cases, you will get to use a {@link SimpleChannelDownstreamHandler} + * to implement a downstream handler because it provides an individual handler + * method for each event type. You might want to implement this interface + * directly though if you want to handle various types of events in more + * generic way. * *
diff --git a/src/main/java/org/jboss/netty/channel/ChannelEvent.java b/src/main/java/org/jboss/netty/channel/ChannelEvent.java index a5c4cf41fb..65dd7edde9 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelEvent.java +++ b/src/main/java/org/jboss/netty/channel/ChannelEvent.java @@ -15,13 +15,19 @@ */ package org.jboss.netty.channel; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.net.SocketAddress; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.socket.ServerSocketChannel; + /** * An I/O event or I/O request associated with a {@link Channel}. *
- * A {@link ChannelEvent} is supposed to be handled by the - * {@link ChannelPipeline} which is attached to the {@link Channel} that - * the event belongs to. Once an event is sent to a {@link ChannelPipeline}, - * it is handled by a list of {@link ChannelHandler}s. + * A {@link ChannelEvent} is handled by a series of {@link ChannelHandler}s in + * a {@link ChannelPipeline}. * *
@@ -33,22 +39,142 @@ package org.jboss.netty.channel; * downstream event and say "an event goes downstream." * (Please refer to the diagram in {@link ChannelPipeline} for more explanation.) *
- * A {@link ChannelEvent} is interpreted differently by a {@link ChannelHandler} - * depending on whether the event is an upstream event or a downstream event. - * An upstream event represents the notification of what happened in the past. - * By contrast, a downstream event represents the request of what should happen - * in the future. For example, a {@link MessageEvent} represents the - * notification of a received message when it goes upstream, while it - * represents the request of writing a message when it goes downstream. + * When your server receives a message from a client, the event associated with + * the received message is an upstream event. When your server sends a message + * or reply to the client, the event associated with the write request is a + * downstream event. The same rule applies for the client side. If your client + * sent a request to the server, it means your client triggered a downstream + * event. If your client received a response from the server, it means + * your client will be notified with an upstream event. Upstream events are + * often the result of inbound operations such as {@link InputStream#read(byte[])}, + * and downstream events are the request for outbound operations such as + * {@link OutputStream#write(byte[])}, {@link Socket#connect(SocketAddress)}, + * and {@link Socket#close()}. * - *
Event name | Event type and condition | Meaning | + *
---|---|---|
{@code "messageReceived"} | + *{@link MessageEvent} | + *a message object (e.g. {@link ChannelBuffer}) was received from a remote peer | + *
{@code "exceptionCaught"} | + *{@link ExceptionEvent} | + *an exception was raised by an I/O thread or a {@link ChannelHandler} | + *
{@code "channelOpen"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code true}) |
+ * a {@link Channel} is open, but not bound nor connected | + *
{@code "channelClosed"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code false}) |
+ * a {@link Channel} was closed and all its related resources were released | + *
{@code "channelBound"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress}) |
+ * a {@link Channel} is open and bound to a local address, but not connected | + *
{@code "channelUnbound"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@code null}) |
+ * a {@link Channel} was unbound from the current local address | + *
{@code "channelConnected"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) |
+ * a {@link Channel} is open, bound to a local address, and connected to a remote address | + *
{@code "writeComplete"} | + *{@link WriteCompletionEvent} | + *something has been written to a remote peer | + *
{@code "channelDisconnected"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@code null}) |
+ * a {@link Channel} was disconnected from its remote peer | + *
{@code "channelInterestChanged"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#INTEREST_OPS INTEREST_OPS}, no value) |
+ * a {@link Channel}'s {@link Channel#getInterestOps() interestOps} was changed | + *
- * Please refer to the documentation of {@link ChannelHandler} and its sub-types - * ({@link ChannelUpstreamHandler} for upstream events and - * {@link ChannelDownstreamHandler} for downstream events) to find out how - * a {@link ChannelEvent} is interpreted depending on the type of the handler - * more in detail. Also, please refer to the {@link ChannelPipeline} - * documentation to find out how an event flows in a pipeline. + * These two additional event types are used only for a parent channel which + * can have a child channel (e.g. {@link ServerSocketChannel}). + *
+ *
Event name | Event type and condition | Meaning | + *
---|---|---|
{@code "childChannelOpen"} | + *{@link ChildChannelStateEvent} ({@code childChannel.isOpen() = true}) |
+ * a child {@link Channel} was open (e.g. a server channel accepted a connection.) | + *
{@code "childChannelClosed"} | + *{@link ChildChannelStateEvent} ({@code childChannel.isOpen() = false}) |
+ * a child {@link Channel} was closed (e.g. the accepted connection was closed.) | + *
Event name | Event type and condition | Meaning | + *
---|---|---|
{@code "write"} | + *{@link MessageEvent} | Send a message to the {@link Channel}. | + *
{@code "bind"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress}) |
+ * Bind the {@link Channel} to the specified local address. | + *
{@code "unbind"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@code null}) |
+ * Unbind the {@link Channel} from the current local address. | + *
{@code "connect"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) |
+ * Connect the {@link Channel} to the specified remote address. | + *
{@code "disconnect"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@code null}) |
+ * Disconnect the {@link Channel} from the current remote address. | + *
{@code "close"} | + *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code false}) |
+ * Close the {@link Channel}. | + *
+ * Other event types and conditions which were not addressed here will be + * ignored and discarded. Please note that there's no {@code "open"} in the + * table. It is because a {@link Channel} is always open when it is created + * by a {@link ChannelFactory}. + * + *
+ * Please refer to the {@link ChannelHandler} and {@link ChannelPipeline} + * documentation to find out how an event flows in a pipeline and how to handle + * the event in your application. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (trustin@gmail.com) diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java index 65a172e311..8772bfcef1 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandlerContext.java @@ -81,8 +81,8 @@ import java.util.concurrent.ConcurrentMap; *
* Please refer to the {@link ChannelHandler}, {@link ChannelEvent}, and * {@link ChannelPipeline} to find out what a upstream event and a downstream - * event are, what fundamental differences they have, and how they flow in a - * pipeline. + * event are, what fundamental differences they have, how they flow in a + * pipeline, and how to handle the event in your application. * * @author The Netty Project (netty-dev@lists.jboss.org) * @author Trustin Lee (trustin@gmail.com) diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java index 28b726d771..c1bb832e7a 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java @@ -15,6 +15,8 @@ */ package org.jboss.netty.channel; +import java.io.InputStream; +import java.io.OutputStream; import java.util.Map; import java.util.NoSuchElementException; @@ -87,20 +89,26 @@ import org.jboss.netty.handler.ssl.SslHandler; * +-------------+--------------------------+---------------+ * | \|/ * +-------------+--------------------------+---------------+ + * | | | | + * | [ Socket.read() ] [ Socket.write() ] | + * | | * | Netty Internal I/O Threads (Transport Implementation) | * +--------------------------------------------------------+ * * An upstream event is handled by the upstream handlers in the bottom-up * direction as shown on the left side of the diagram. An upstream handler - * usually handles the inbound data received from the I/O thread on the bottom - * of the diagram. If an upstream event goes beyond the top upstream handler, - * it is discarded silently. + * usually handles the inbound data generated by the I/O thread on the bottom + * of the diagram. The inbound data is often read from a remote peer via the + * actual input operation such as {@link InputStream#read(byte[])}. + * If an upstream event goes beyond the top upstream handler, it is discarded + * silently. *
* A downstream event is handled by the downstream handler in the top-down * direction as shown on the right side of the diagram. A downstream handler * usually generates or transforms the outbound traffic such as write requests. * If a downstream event goes beyond the bottom downstream handler, it is - * handled by an I/O thread associated with the {@link Channel}. + * handled by an I/O thread associated with the {@link Channel}. The I/O thread + * often performs the actual output operation such as {@link OutputStream#write(byte[])}. *
* For example, let us assume that we created the following pipeline: *
diff --git a/src/main/java/org/jboss/netty/channel/ChannelUpstreamHandler.java b/src/main/java/org/jboss/netty/channel/ChannelUpstreamHandler.java index f8e7e237f1..0e7aa52c80 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelUpstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelUpstreamHandler.java @@ -15,11 +15,8 @@ */ package org.jboss.netty.channel; -import java.net.SocketAddress; import java.util.concurrent.Executor; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.socket.ServerSocketChannel; import org.jboss.netty.handler.execution.ExecutionHandler; import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor; @@ -27,100 +24,14 @@ import org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor; /** * Handles or intercepts an upstream {@link ChannelEvent}, and sends a * {@link ChannelEvent} to the next handler in a {@link ChannelPipeline}. + *+ * The most common use case of this interface is to intercept an I/O event + * generated by I/O workers to transform the received messages or execute + * the relevant business logic. * - *
Upstream events
+ *{@link SimpleChannelUpstreamHandler}
*- * An upstream event is an event which is supposed to be processed by - * a series of upstream handlers in the {@link ChannelPipeline}. - * The upstream events are generated by an I/O thread, and they have the - * following meaning: - *
- *
Event name | Event type and condition | Meaning | - *
---|---|---|
{@code "messageReceived"} | - *{@link MessageEvent} | - *a message object (e.g. {@link ChannelBuffer}) was received from a remote peer | - *
{@code "exceptionCaught"} | - *{@link ExceptionEvent} | - *an exception was raised by an I/O thread or a {@link ChannelHandler} | - *
{@code "channelOpen"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code true}) |
- * a {@link Channel} is open, but not bound nor connected | - *
{@code "channelClosed"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#OPEN OPEN}, value = {@code false}) |
- * a {@link Channel} was closed and all its related resources were released | - *
{@code "channelBound"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress}) |
- * a {@link Channel} is open and bound to a local address, but not connected | - *
{@code "channelUnbound"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#BOUND BOUND}, value = {@code null}) |
- * a {@link Channel} was unbound from the current local address | - *
{@code "channelConnected"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) |
- * a {@link Channel} is open, bound to a local address, and connected to a remote address | - *
{@code "writeComplete"} | - *{@link WriteCompletionEvent} | - *something has been written to a remote peer | - *
{@code "channelDisconnected"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#CONNECTED CONNECTED}, value = {@code null}) |
- * a {@link Channel} was disconnected from its remote peer | - *
{@code "channelInterestChanged"} | - *{@link ChannelStateEvent} (state = {@link ChannelState#INTEREST_OPS INTEREST_OPS}, no value) |
- * a {@link Channel}'s {@link Channel#getInterestOps() interestOps} was changed | - *
- * These two additional event types are used only for a parent channel which - * can have a child channel (e.g. {@link ServerSocketChannel}). - *
- *
Event name | Event type and condition | Meaning | - *
---|---|---|
{@code "childChannelOpen"} | - *{@link ChildChannelStateEvent} ({@code childChannel.isOpen() = true}) |
- * a child {@link Channel} was open (e.g. a server channel accepted a connection.) | - *
{@code "childChannelClosed"} | - *{@link ChildChannelStateEvent} ({@code childChannel.isOpen() = false}) |
- * a child {@link Channel} was closed (e.g. the accepted connection was closed.) | - *
- * You might want to refer to {@link ChannelDownstreamHandler} to see how a - * {@link ChannelEvent} is interpreted when going downstream. Also, please - * refer to the {@link ChannelEvent} and {@link ChannelPipeline} documentation - * to find out what an upstream event and a downstream event are, what - * fundamental differences they have, and how they flow in a pipeline. - * - *
- * In most cases, you will get to use a {@link SimpleChannelHandler} to + * In most cases, you will get to use a {@link SimpleChannelUpstreamHandler} to * implement an upstream handler because it provides an individual handler * method for each event type. You might want to implement this interface * directly though if you want to handle various types of events in more