Add more convenient methods to ChannelPipeline

.. to simplify pipeline construction as shown in the echo example
This commit is contained in:
Trustin Lee 2012-05-15 14:08:42 +09:00
parent d01d1d0843
commit 6eb540ca40
6 changed files with 83 additions and 34 deletions

View File

@ -20,7 +20,6 @@ import io.netty.channel.ChannelBootstrap;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoop; import io.netty.channel.EventLoop;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.socket.nio.SelectorEventLoop; import io.netty.channel.socket.nio.SelectorEventLoop;
@ -60,9 +59,9 @@ public class EchoClient {
.initializer(new ChannelInitializer() { .initializer(new ChannelInitializer() {
@Override @Override
public void initChannel(Channel ch) throws Exception { public void initChannel(Channel ch) throws Exception {
ChannelPipeline p = ch.pipeline(); ch.pipeline().addLast(
p.addLast("logger", new LoggingHandler(LogLevel.INFO)); new LoggingHandler(LogLevel.INFO),
p.addLast("echoer", new EchoClientHandler(firstMessageSize)); new EchoClientHandler(firstMessageSize));
} }
}); });

View File

@ -19,7 +19,6 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.ServerChannelBootstrap; import io.netty.channel.ServerChannelBootstrap;
import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.SelectorEventLoop; import io.netty.channel.socket.nio.SelectorEventLoop;
@ -51,9 +50,9 @@ public class EchoServer {
.childInitializer(new ChannelInitializer() { .childInitializer(new ChannelInitializer() {
@Override @Override
public void initChannel(Channel ch) throws Exception { public void initChannel(Channel ch) throws Exception {
ChannelPipeline p = ch.pipeline(); ch.pipeline().addLast(
p.addLast("logger", new LoggingHandler(LogLevel.INFO)); new LoggingHandler(LogLevel.INFO),
p.addLast("echoer", new EchoServerHandler()); new EchoServerHandler());
} }
}); });

View File

@ -125,7 +125,7 @@ public class ChannelBootstrap {
} }
ChannelPipeline p = channel.pipeline(); ChannelPipeline p = channel.pipeline();
p.addLast(generateName(initializer), initializer); p.addLast(DefaultChannelPipeline.generateName(initializer), initializer);
for (Entry<ChannelOption<?>, Object> e: options.entrySet()) { for (Entry<ChannelOption<?>, Object> e: options.entrySet()) {
try { try {
@ -157,14 +157,4 @@ public class ChannelBootstrap {
throw new IllegalStateException("initializer not set"); throw new IllegalStateException("initializer not set");
} }
} }
static String generateName(ChannelHandler handler) {
String type = handler.getClass().getSimpleName();
StringBuilder buf = new StringBuilder(type.length() + 10);
buf.append(type);
buf.append("-0");
buf.append(Long.toHexString(System.identityHashCode(handler) & 0xFFFFFFFFL | 0x100000000L));
buf.setCharAt(buf.length() - 9, 'x');
return buf.toString();
}
} }

View File

@ -216,7 +216,7 @@ public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundI
* @throws NullPointerException * @throws NullPointerException
* if the specified name or handler is {@code null} * if the specified name or handler is {@code null}
*/ */
void addFirst(String name, ChannelHandler handler); ChannelPipeline addFirst(String name, ChannelHandler handler);
/** /**
* Appends a {@link ChannelHandler} at the last position of this pipeline. * Appends a {@link ChannelHandler} at the last position of this pipeline.
@ -229,7 +229,7 @@ public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundI
* @throws NullPointerException * @throws NullPointerException
* if the specified name or handler is {@code null} * if the specified name or handler is {@code null}
*/ */
void addLast(String name, ChannelHandler handler); ChannelPipeline addLast(String name, ChannelHandler handler);
/** /**
* Inserts a {@link ChannelHandler} before an existing handler of this * Inserts a {@link ChannelHandler} before an existing handler of this
@ -246,7 +246,7 @@ public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundI
* @throws NullPointerException * @throws NullPointerException
* if the specified baseName, name, or handler is {@code null} * if the specified baseName, name, or handler is {@code null}
*/ */
void addBefore(String baseName, String name, ChannelHandler handler); ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
/** /**
* Inserts a {@link ChannelHandler} after an existing handler of this * Inserts a {@link ChannelHandler} after an existing handler of this
@ -263,7 +263,10 @@ public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundI
* @throws NullPointerException * @throws NullPointerException
* if the specified baseName, name, or handler is {@code null} * if the specified baseName, name, or handler is {@code null}
*/ */
void addAfter(String baseName, String name, ChannelHandler handler); ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
ChannelPipeline addFirst(ChannelHandler... handlers);
ChannelPipeline addLast(ChannelHandler... handlers);
/** /**
* Removes the specified {@link ChannelHandler} from this pipeline. * Removes the specified {@link ChannelHandler} from this pipeline.

View File

@ -55,7 +55,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
} }
@Override @Override
public synchronized void addFirst(String name, ChannelHandler handler) { public synchronized ChannelPipeline addFirst(String name, ChannelHandler handler) {
if (name2ctx.isEmpty()) { if (name2ctx.isEmpty()) {
init(name, handler); init(name, handler);
} else { } else {
@ -71,10 +71,12 @@ public class DefaultChannelPipeline implements ChannelPipeline {
callAfterAdd(newHead); callAfterAdd(newHead);
} }
return this;
} }
@Override @Override
public synchronized void addLast(String name, ChannelHandler handler) { public synchronized ChannelPipeline addLast(String name, ChannelHandler handler) {
if (name2ctx.isEmpty()) { if (name2ctx.isEmpty()) {
init(name, handler); init(name, handler);
} else { } else {
@ -90,10 +92,12 @@ public class DefaultChannelPipeline implements ChannelPipeline {
callAfterAdd(newTail); callAfterAdd(newTail);
} }
return this;
} }
@Override @Override
public synchronized void addBefore(String baseName, String name, ChannelHandler handler) { public synchronized ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) {
DefaultChannelHandlerContext ctx = getContextOrDie(baseName); DefaultChannelHandlerContext ctx = getContextOrDie(baseName);
if (ctx == head) { if (ctx == head) {
addFirst(name, handler); addFirst(name, handler);
@ -109,10 +113,12 @@ public class DefaultChannelPipeline implements ChannelPipeline {
callAfterAdd(newCtx); callAfterAdd(newCtx);
} }
return this;
} }
@Override @Override
public synchronized void addAfter(String baseName, String name, ChannelHandler handler) { public synchronized ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler) {
DefaultChannelHandlerContext ctx = getContextOrDie(baseName); DefaultChannelHandlerContext ctx = getContextOrDie(baseName);
if (ctx == tail) { if (ctx == tail) {
addLast(name, handler); addLast(name, handler);
@ -128,6 +134,58 @@ public class DefaultChannelPipeline implements ChannelPipeline {
callAfterAdd(newCtx); callAfterAdd(newCtx);
} }
return this;
}
@Override
public ChannelPipeline addFirst(ChannelHandler... handlers) {
if (handlers == null) {
throw new NullPointerException("handlers");
}
if (handlers[0] == null) {
return this;
}
int size;
for (size = 1; size < handlers.length; size ++) {
if (handlers[size] == null) {
break;
}
}
for (int i = size - 1; i >= 0; i --) {
ChannelHandler h = handlers[i];
addFirst(generateName(h), h);
}
return this;
}
@Override
public ChannelPipeline addLast(ChannelHandler... handlers) {
if (handlers == null) {
throw new NullPointerException("handlers");
}
for (ChannelHandler h: handlers) {
if (h == null) {
break;
}
addLast(generateName(h), h);
}
return this;
}
static String generateName(ChannelHandler handler) {
String type = handler.getClass().getSimpleName();
StringBuilder buf = new StringBuilder(type.length() + 10);
buf.append(type);
buf.append("-0");
buf.append(Long.toHexString(System.identityHashCode(handler) & 0xFFFFFFFFL | 0x100000000L));
buf.setCharAt(buf.length() - 9, 'x');
return buf.toString();
} }
@Override @Override

View File

@ -22,7 +22,7 @@ public class ServerChannelBootstrap {
@Override @Override
public void initChannel(Channel ch) throws Exception { public void initChannel(Channel ch) throws Exception {
Acceptor acceptor = new Acceptor(); Acceptor acceptor = new Acceptor();
ch.pipeline().addLast(ChannelBootstrap.generateName(acceptor), acceptor); ch.pipeline().addLast(DefaultChannelPipeline.generateName(acceptor), acceptor);
} }
}; };
@ -119,9 +119,9 @@ public class ServerChannelBootstrap {
ChannelPipeline p = channel.pipeline(); ChannelPipeline p = channel.pipeline();
if (initializer != null) { if (initializer != null) {
p.addLast(ChannelBootstrap.generateName(initializer), initializer); p.addLast(DefaultChannelPipeline.generateName(initializer), initializer);
} }
p.addLast(ChannelBootstrap.generateName(acceptor), acceptor); p.addLast(DefaultChannelPipeline.generateName(acceptor), acceptor);
ChannelFuture f = parentEventLoop.register(channel).awaitUninterruptibly(); ChannelFuture f = parentEventLoop.register(channel).awaitUninterruptibly();
if (!f.isSuccess()) { if (!f.isSuccess()) {
@ -178,7 +178,7 @@ public class ServerChannelBootstrap {
break; break;
} }
child.pipeline().addLast(ChannelBootstrap.generateName(childInitializer), childInitializer); child.pipeline().addLast(DefaultChannelPipeline.generateName(childInitializer), childInitializer);
for (Entry<ChannelOption<?>, Object> e: childOptions.entrySet()) { for (Entry<ChannelOption<?>, Object> e: childOptions.entrySet()) {
try { try {