Fixed issue: NETTY-54 (Improve SimpleChannelHandler to implement ChannelDownstreamHandler)

Fixed issue: NETTY-55 (Channel.unbind() method is missing.)
This commit is contained in:
Trustin Lee 2008-10-02 04:40:46 +00:00
parent 6c2230aac2
commit da04e2cae9
5 changed files with 172 additions and 12 deletions

View File

@ -150,6 +150,10 @@ public abstract class AbstractChannel implements Channel, Comparable<Channel> {
return Channels.bind(this, localAddress);
}
public ChannelFuture unbind() {
return Channels.unbind(this);
}
public ChannelFuture close() {
return Channels.close(this);
}

View File

@ -220,6 +220,14 @@ public interface Channel {
*/
ChannelFuture disconnect();
/**
* Unbinds this channel from the current local address asynchronously.
*
* @return the {@link ChannelFuture} which will be notified when the
* unbind request succeeds or fails
*/
ChannelFuture unbind();
/**
* Closes this channel asynchronously. If this channel is bound or
* connected, it will be disconnected and unbound first.

View File

@ -502,6 +502,39 @@ public class Channels {
channel, future, ChannelState.BOUND, localAddress));
}
/**
* Sends a {@code "unbind"} request to the previous
* {@link ChannelDownstreamHandler} in the {@link ChannelPipeline} where
* the specified {@link ChannelHandlerContext} belongs.
*
* @param ctx the context
* @param channel the channel to unbind
* @param future the future which will be notified when the unbind
* operation is done
*/
public static void unbind(
ChannelHandlerContext ctx, Channel channel, ChannelFuture future) {
ctx.sendDownstream(new DefaultChannelStateEvent(
channel, future, ChannelState.BOUND, null));
}
/**
* Sends a {@code "unbind"} request to the last
* {@link ChannelDownstreamHandler} in the {@link ChannelPipeline} of
* the specified {@link Channel}.
*
* @param channel the channel to unbind
*
* @return the {@link ChannelFuture} which will be notified when the
* unbind operation is done
*/
public static ChannelFuture unbind(Channel channel) {
ChannelFuture future = future(channel);
channel.getPipeline().sendDownstream(new DefaultChannelStateEvent(
channel, future, ChannelState.BOUND, null));
return future;
}
/**
* Sends a {@code "connect"} request to the last
* {@link ChannelDownstreamHandler} in the {@link ChannelPipeline} of

View File

@ -22,24 +22,31 @@
*/
package org.jboss.netty.channel;
import java.net.SocketAddress;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.logging.InternalLogger;
import org.jboss.netty.logging.InternalLoggerFactory;
/**
* A {@link ChannelUpstreamHandler} which provides an individual handler method
* for each event type. This handler down-casts the received upstream event
* into more meaningful sub-type event and calls an appropriate handler method
* with the down-cast event. The names of the methods are identical to the
* upstream event names, as introduced in the {@link ChannelUpstreamHandler}
* documentation.
* A {@link ChannelHandler} which provides an individual handler method
* for each event type. This handler down-casts the received upstream or
* or downstream event into more meaningful sub-type event and calls an
* appropriate handler method with the down-cast event. For an upstream
* event, the names of the methods are identical to the upstream event names,
* as introduced in the {@link ChannelUpstreamHandler} documentation. For a
* downstream event, the names of the methods starts with the name of the
* operation and ends with {@code "Requested"}
* (e.g. {@link #writeRequested(ChannelHandlerContext, MessageEvent) writeRequested}.)
*
* <h3>Overriding the {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream} method</h3>
* <h3>Overriding the {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream}
* and {@link #handleDownstream(ChannelHandlerContext, ChannelEvent) handleDownstream} method</h3>
* <p>
* You can override the {@link #handleUpstream(ChannelHandlerContext, ChannelEvent) handleUpstream}
* method just like you can do with other {@link ChannelUpstreamHandler}s.
* However, please make sure that you call {@code super.handleUpstream()} so
* and {@link #handleDownstream(ChannelHandlerContext, ChannelEvent) handleDownstream}
* method just like overriding an ordinary Java method. Please make sure to
* call {@code super.handleUpstream()} or {@code super.handleDownstream()} so
* that other handler methods are invoked properly:
* </p>
* <pre>public class MyChannelHandler extends SimpleChannelHandler {
@ -53,6 +60,16 @@ import org.jboss.netty.logging.InternalLoggerFactory;
*
* <strong>super.handleUpstream(ctx, e);</strong>
* }
*
* public void handleDownstream({@link ChannelHandlerContext} ctx, {@link ChannelEvent} e) throws Exception {
*
* // Log all channel state changes.
* if (e instanceof MessageEvent) {
* logger.info("Writing:: " + e);
* }
*
* <strong>super.handleDownstream(ctx, e);</strong>
* }
* }</pre>
*
* @author The Netty Project (netty-dev@lists.jboss.org)
@ -60,7 +77,7 @@ import org.jboss.netty.logging.InternalLoggerFactory;
*
* @version $Rev$, $Date$
*/
public class SimpleChannelHandler implements ChannelUpstreamHandler {
public class SimpleChannelHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler {
private static final InternalLogger logger =
InternalLoggerFactory.getInstance(SimpleChannelHandler.class.getName());
@ -116,6 +133,8 @@ public class SimpleChannelHandler implements ChannelUpstreamHandler {
case INTEREST_OPS:
channelInterestChanged(ctx, evt);
break;
default:
ctx.sendDownstream(e);
}
} else if (e instanceof ExceptionEvent) {
exceptionCaught(ctx, (ExceptionEvent) e);
@ -224,4 +243,100 @@ public class SimpleChannelHandler implements ChannelUpstreamHandler {
ChannelHandlerContext ctx, ChildChannelStateEvent e) throws Exception {
ctx.sendUpstream(e);
}
/**
* {@inheritDoc} Down-casts the received downstream event into more
* meaningful sub-type event and calls an appropriate handler method with
* the down-casted event.
*/
public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
throws Exception {
if (e instanceof MessageEvent) {
writeRequested(ctx, (MessageEvent) e);
} else if (e instanceof ChannelStateEvent) {
ChannelStateEvent evt = (ChannelStateEvent) e;
switch (evt.getState()) {
case OPEN:
if (!Boolean.TRUE.equals(evt.getValue())) {
closeRequested(ctx, evt);
}
break;
case BOUND:
if (evt.getValue() != null) {
bindRequested(ctx, evt);
} else {
unbindRequested(ctx, evt);
}
break;
case CONNECTED:
if (evt.getValue() != null) {
connectRequested(ctx, evt);
} else {
disconnectRequested(ctx, evt);
}
break;
case INTEREST_OPS:
setInterestOpsRequested(ctx, evt);
break;
default:
ctx.sendDownstream(e);
}
} else {
ctx.sendDownstream(e);
}
}
/**
* Invoked when {@link Channel#write(Object)} is called.
*/
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#bind(SocketAddress)} was called.
*/
public void bindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#connect(SocketAddress)} was called.
*/
public void connectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#setInterestOps(int)} was called.
*/
public void setInterestOpsRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#disconnect()} was called.
*/
public void disconnectRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#unbind()} was called.
*/
public void unbindRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
/**
* Invoked when {@link Channel#close()} was called.
*/
public void closeRequested(ChannelHandlerContext ctx, ChannelStateEvent e) {
ctx.sendDownstream(e);
}
}

View File

@ -39,7 +39,6 @@ import javax.net.ssl.SSLEngineResult.Status;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelDownstreamHandler;
import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
@ -96,7 +95,7 @@ import org.jboss.netty.util.ImmediateExecutor;
* @apiviz.landmark
* @apiviz.uses org.jboss.netty.handler.ssl.SslBufferPool
*/
public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler {
public class SslHandler extends FrameDecoder {
private static final ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0);
@ -293,6 +292,7 @@ public class SslHandler extends FrameDecoder implements ChannelDownstreamHandler
return channel.getPipeline().getContext(getClass());
}
@Override
public void handleDownstream(
final ChannelHandlerContext context, final ChannelEvent evt) throws Exception {
if (evt instanceof ChannelStateEvent) {