From 9024bc8704475c6429cdb17331f4a393dc2595e3 Mon Sep 17 00:00:00 2001 From: norman Date: Tue, 22 May 2012 13:35:20 +0200 Subject: [PATCH] Allow to bind a client channel in a seperate step. This can be useful if you want to pass an object on connect to your handlers. Kind of related to #275 --- .../netty/bootstrap/ClientBootstrap.java | 65 +++++++++++++++++++ .../jboss/netty/channel/AbstractChannel.java | 8 +++ .../java/org/jboss/netty/channel/Channel.java | 15 +++++ 3 files changed, 88 insertions(+) diff --git a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java index aa446c435d..7b1c41ced3 100644 --- a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java +++ b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java @@ -229,4 +229,69 @@ public class ClientBootstrap extends Bootstrap { // Connect. return ch.connect(remoteAddress); } + + /** + * Attempts to bind a channel with the specified {@code localAddress}. later the channel can be connected + * to a remoteAddress by calling {@link Channel#connect(SocketAddress)}.This method is useful where bind and connect + * need to be done in separate steps. + * + * This can also be useful if you want to set and attachment to the {@link Channel} via + * {@link Channel#setAttachment(Object)} so you can use it after the {@link #bind(SocketAddress)} was done. + *
+ * For example: + * + *
+     *  ChannelFuture bindFuture = boostrap.bind(new InetSocketAddress("192.168.0.15", 0));
+     *  Channel channel = bindFuture.getChannel();
+     *  channel.setAttachment(dataObj);
+     *  boostrap.connect(new InetSocketAddress("192.168.0.30", 8080));
+     * 
+ *
+ * + * You can use it then in your handlers like this: + * + *
+     *  public class YourHandler extends SimpleChannelUpstreamHandler {
+     *      public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+     *          Object dataObject = ctx.getChannel().getAttachement();
+     *      }
+     *  }
+     *  
+     * 
+ * + * @return a future object which notifies when this bind attempt + * succeeds or fails + * + * @throws ChannelPipelineException + * if this bootstrap's {@link #setPipelineFactory(ChannelPipelineFactory) pipelineFactory} + * failed to create a new {@link ChannelPipeline} + */ + public ChannelFuture bind(final SocketAddress localAddress) { + + if (localAddress == null) { + throw new NullPointerException("localAddress"); + } + + ChannelPipeline pipeline; + try { + pipeline = getPipelineFactory().getPipeline(); + } catch (Exception e) { + throw new ChannelPipelineException("Failed to initialize a pipeline.", e); + } + + // Set the options. + Channel ch = getFactory().newChannel(pipeline); + boolean success = false; + try { + ch.getConfig().setOptions(getOptions()); + success = true; + } finally { + if (!success) { + ch.close(); + } + } + + // Bind. + return ch.bind(localAddress); + } } diff --git a/src/main/java/org/jboss/netty/channel/AbstractChannel.java b/src/main/java/org/jboss/netty/channel/AbstractChannel.java index 4f8aac114f..98e0105217 100644 --- a/src/main/java/org/jboss/netty/channel/AbstractChannel.java +++ b/src/main/java/org/jboss/netty/channel/AbstractChannel.java @@ -53,6 +53,7 @@ public abstract class AbstractChannel implements Channel { /** Cache for the string representation of this channel */ private boolean strValConnected; private String strVal; + private volatile Object attachment; /** * Creates a new instance. @@ -249,6 +250,13 @@ public abstract class AbstractChannel implements Channel { return Channels.write(this, message, remoteAddress); } + public Object getAttachment() { + return attachment; + } + + public void setAttachment(Object attachment) { + this.attachment = attachment; + } /** * Returns the {@link String} representation of this channel. The returned * string contains the {@linkplain #getId() ID}, {@linkplain #getLocalAddress() local address}, diff --git a/src/main/java/org/jboss/netty/channel/Channel.java b/src/main/java/org/jboss/netty/channel/Channel.java index e248941d0d..b127bebad4 100644 --- a/src/main/java/org/jboss/netty/channel/Channel.java +++ b/src/main/java/org/jboss/netty/channel/Channel.java @@ -359,4 +359,19 @@ public interface Channel extends Comparable { * {@code interestOps} change request succeeds or fails */ ChannelFuture setReadable(boolean readable); + + /** + * Retrieves an object which is {@link #setAttachment(Object) attached} to + * this {@link Channel}. + * + * @return {@code null} if no object was attached or {@code null} was + * attached + */ + Object getAttachment(); + + /** + * Attaches an object to this {@link Channel} to store a stateful + * information + */ + void setAttachment(Object attachment); }