View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.channel;
    17
    18  import java.net.InetSocketAddress;
    19  import java.net.SocketAddress;
    20  import java.nio.channels.NotYetConnectedException;
    21  import java.nio.channels.SelectionKey;
    22
    23  import org.jboss.netty.channel.socket.DatagramChannel;
    24  import org.jboss.netty.channel.socket.ServerSocketChannel;
    25  import org.jboss.netty.channel.socket.SocketChannel;
    26  import org.jboss.netty.channel.socket.nio.NioSocketChannelConfig;
    27
    28
    29  /**
    30   * A nexus to a network socket or a component which is capable of I/O
    31   * operations such as read, write, connect, and bind.
    32   * <p>
    33   * A channel provides a user:
    34   * <ul>
    35   * <li>the current state of the channel (e.g. is it open? is it connected?),</li>
    36   * <li>the {@linkplain ChannelConfig configuration parameters} of the channel (e.g. receive buffer size),</li>
    37   * <li>the I/O operations that the channel supports (e.g. read, write, connect, and bind), and</li>
    38   * <li>the {@link ChannelPipeline} which handles all {@linkplain ChannelEvent I/O events and requests}
    39   *     associated with the channel.</li>
    40   * </ul>
    41   *
    42   * <h3>All I/O operations are asynchronous.</h3>
    43   * <p>
    44   * All I/O operations in Netty are asynchronous.  It means any I/O calls will
    45   * return immediately with no guarantee that the requested I/O operation has
    46   * been completed at the end of the call.  Instead, you will be returned with
    47   * a {@link ChannelFuture} instance which will notify you when the requested I/O
    48   * operation has succeeded, failed, or canceled.
    49   *
    50   * <h3>Channels are hierarchical</h3>
    51   * <p>
    52   * A {@link Channel} can have a {@linkplain #getParent() parent} depending on
    53   * how it was created.  For instance, a {@link SocketChannel}, that was accepted
    54   * by {@link ServerSocketChannel}, will return the {@link ServerSocketChannel}
    55   * as its parent on {@link #getParent()}.
    56   * <p>
    57   * The semantics of the hierarchical structure depends on the transport
    58   * implementation where the {@link Channel} belongs to.  For example, you could
    59   * write a new {@link Channel} implementation that creates the sub-channels that
    60   * share one socket connection, as <a href="http://beepcore.org/">BEEP</a> and
    61   * <a href="http://en.wikipedia.org/wiki/Secure_Shell">SSH</a> do.
    62   *
    63   * <h3>Downcast to access transport-specific operations</h3>
    64   * <p>
    65   * Some transports exposes additional operations that is specific to the
    66   * transport.  Down-cast the {@link Channel} to sub-type to invoke such
    67   * operations.  For example, with the old I/O datagram transport, multicast
    68   * join / leave operations are provided by {@link DatagramChannel}.
    69   *
    70   * <h3>InterestOps</h3>
    71   * <p>
    72   * A {@link Channel} has a property called {@link #getInterestOps() interestOps}
    73   * which is similar to that of {@link SelectionKey#interestOps() NIO SelectionKey}.
    74   * It is represented as a <a href="http://en.wikipedia.org/wiki/Bit_field">bit
    75   * field</a> which is composed of the two flags.
    76   * <ul>
    77   * <li>{@link #OP_READ} - If set, a message sent by a remote peer will be read
    78   *     immediately.  If unset, the message from the remote peer will not be read
    79   *     until the {@link #OP_READ} flag is set again (i.e. read suspension).</li>
    80   * <li>{@link #OP_WRITE} - If set, a write request will not be sent to a remote
    81   *     peer until the {@link #OP_WRITE} flag is cleared and the write request
    82   *     will be pending in a queue.  If unset, the write request will be flushed
    83   *     out as soon as possible from the queue.</li>
    84   * <li>{@link #OP_READ_WRITE} - This is a combination of {@link #OP_READ} and
    85   *     {@link #OP_WRITE}, which means only write requests are suspended.</li>
    86   * <li>{@link #OP_NONE} - This is a combination of (NOT {@link #OP_READ}) and
    87   *     (NOT {@link #OP_WRITE}), which means only read operation is suspended.</li>
    88   * </ul>
    89   * </p><p>
    90   * You can set or clear the {@link #OP_READ} flag to suspend and resume read
    91   * operation via {@link #setReadable(boolean)}.
    92   * </p><p>
    93   * Please note that you cannot suspend or resume write operation just like you
    94   * can set or clear {@link #OP_READ}. The {@link #OP_WRITE} flag is read only
    95   * and provided simply as a mean to tell you if the size of pending write
    96   * requests exceeded a certain threshold or not so that you don't issue too many
    97   * pending writes that lead to an {@link OutOfMemoryError}.  For example, the
    98   * NIO socket transport uses the {@code writeBufferLowWaterMark} and
    99   * {@code writeBufferHighWaterMark} properties in {@link NioSocketChannelConfig}
    100  * to determine when to set or clear the {@link #OP_WRITE} flag.
    101  * </p>
    102  *
    103  * @apiviz.landmark
    104  * @apiviz.composedOf org.jboss.netty.channel.ChannelConfig
    105  * @apiviz.composedOf org.jboss.netty.channel.ChannelPipeline
    106  *
    107  * @apiviz.exclude ^org\.jboss\.netty\.channel\.([a-z]+\.)+[^\.]+Channel$
    108  */
    109 public interface Channel extends Comparable<Channel> {
    110
    111     /**
    112      * The {@link #getInterestOps() interestOps} value which tells that only
    113      * read operation has been suspended.
    114      */
    115     int OP_NONE = 0;
    116
    117     /**
    118      * The {@link #getInterestOps() interestOps} value which tells that neither
    119      * read nor write operation has been suspended.
    120      */
    121     int OP_READ = 1;
    122
    123     /**
    124      * The {@link #getInterestOps() interestOps} value which tells that both
    125      * read and write operation has been suspended.
    126      */
    127     int OP_WRITE = 4;
    128
    129     /**
    130      * The {@link #getInterestOps() interestOps} value which tells that only
    131      * write operation has been suspended.
    132      */
    133     int OP_READ_WRITE = OP_READ | OP_WRITE;
    134
    135     /**
    136      * Returns the unique integer ID of this channel.
    137      */
    138     Integer getId();
    139
    140     /**
    141      * Returns the {@link ChannelFactory} which created this channel.
    142      */
    143     ChannelFactory getFactory();
    144
    145     /**
    146      * Returns the parent of this channel.
    147      *
    148      * @return the parent channel.
    149      *         {@code null} if this channel does not have a parent channel.
    150      */
    151     Channel getParent();
    152
    153     /**
    154      * Returns the configuration of this channel.
    155      */
    156     ChannelConfig getConfig();
    157
    158     /**
    159      * Returns the {@link ChannelPipeline} which handles {@link ChannelEvent}s
    160      * associated with this channel.
    161      */
    162     ChannelPipeline getPipeline();
    163
    164     /**
    165      * Returns {@code true} if and only if this channel is open.
    166      */
    167     boolean isOpen();
    168
    169     /**
    170      * Returns {@code true} if and only if this channel is bound to a
    171      * {@linkplain #getLocalAddress() local address}.
    172      */
    173     boolean isBound();
    174
    175     /**
    176      * Returns {@code true} if and only if this channel is connected to a
    177      * {@linkplain #getRemoteAddress() remote address}.
    178      */
    179     boolean isConnected();
    180
    181     /**
    182      * Returns the local address where this channel is bound to.  The returned
    183      * {@link SocketAddress} is supposed to be down-cast into more concrete
    184      * type such as {@link InetSocketAddress} to retrieve the detailed
    185      * information.
    186      *
    187      * @return the local address of this channel.
    188      *         {@code null} if this channel is not bound.
    189      */
    190     SocketAddress getLocalAddress();
    191
    192     /**
    193      * Returns the remote address where this channel is connected to.  The
    194      * returned {@link SocketAddress} is supposed to be down-cast into more
    195      * concrete type such as {@link InetSocketAddress} to retrieve the detailed
    196      * information.
    197      *
    198      * @return the remote address of this channel.
    199      *         {@code null} if this channel is not connected.
    200      *         If this channel is not connected but it can receive messages
    201      *         from arbitrary remote addresses (e.g. {@link DatagramChannel},
    202      *         use {@link MessageEvent#getRemoteAddress()} to determine
    203      *         the origination of the received message as this method will
    204      *         return {@code null}.
    205      */
    206     SocketAddress getRemoteAddress();
    207
    208     /**
    209      * Sends a message to this channel asynchronously.    If this channel was
    210      * created by a connectionless transport (e.g. {@link DatagramChannel})
    211      * and is not connected yet, you have to call {@link #write(Object, SocketAddress)}
    212      * instead.  Otherwise, the write request will fail with
    213      * {@link NotYetConnectedException} and an {@code 'exceptionCaught'} event
    214      * will be triggered.
    215      *
    216      * @param message the message to write
    217      *
    218      * @return the {@link ChannelFuture} which will be notified when the
    219      *         write request succeeds or fails
    220      *
    221      * @throws NullPointerException if the specified message is {@code null}
    222      */
    223     ChannelFuture write(Object message);
    224
    225     /**
    226      * Sends a message to this channel asynchronously.  It has an additional
    227      * parameter that allows a user to specify where to send the specified
    228      * message instead of this channel's current remote address.  If this
    229      * channel was created by a connectionless transport (e.g. {@link DatagramChannel})
    230      * and is not connected yet, you must specify non-null address.  Otherwise,
    231      * the write request will fail with {@link NotYetConnectedException} and
    232      * an {@code 'exceptionCaught'} event will be triggered.
    233      *
    234      * @param message       the message to write
    235      * @param remoteAddress where to send the specified message.
    236      *                      This method is identical to {@link #write(Object)}
    237      *                      if {@code null} is specified here.
    238      *
    239      * @return the {@link ChannelFuture} which will be notified when the
    240      *         write request succeeds or fails
    241      *
    242      * @throws NullPointerException if the specified message is {@code null}
    243      */
    244     ChannelFuture write(Object message, SocketAddress remoteAddress);
    245
    246     /**
    247      * Binds this channel to the specified local address asynchronously.
    248      *
    249      * @param localAddress where to bind
    250      *
    251      * @return the {@link ChannelFuture} which will be notified when the
    252      *         bind request succeeds or fails
    253      *
    254      * @throws NullPointerException if the specified address is {@code null}
    255      */
    256     ChannelFuture bind(SocketAddress localAddress);
    257
    258     /**
    259      * Connects this channel to the specified remote address asynchronously.
    260      *
    261      * @param remoteAddress where to connect
    262      *
    263      * @return the {@link ChannelFuture} which will be notified when the
    264      *         connection request succeeds or fails
    265      *
    266      * @throws NullPointerException if the specified address is {@code null}
    267      */
    268     ChannelFuture connect(SocketAddress remoteAddress);
    269
    270     /**
    271      * Disconnects this channel from the current remote address asynchronously.
    272      *
    273      * @return the {@link ChannelFuture} which will be notified when the
    274      *         disconnection request succeeds or fails
    275      */
    276     ChannelFuture disconnect();
    277
    278     /**
    279      * Unbinds this channel from the current local address asynchronously.
    280      *
    281      * @return the {@link ChannelFuture} which will be notified when the
    282      *         unbind request succeeds or fails
    283      */
    284     ChannelFuture unbind();
    285
    286     /**
    287      * Closes this channel asynchronously.  If this channel is bound or
    288      * connected, it will be disconnected and unbound first.  Once a channel
    289      * is closed, it can not be open again.  Calling this method on a closed
    290      * channel has no effect.  Please note that this method always returns the
    291      * same future instance.
    292      *
    293      * @return the {@link ChannelFuture} which will be notified when the
    294      *         close request succeeds or fails
    295      */
    296     ChannelFuture close();
    297
    298     /**
    299      * Returns the {@link ChannelFuture} which will be notified when this
    300      * channel is closed.  This method always returns the same future instance.
    301      */
    302     ChannelFuture getCloseFuture();
    303
    304     /**
    305      * Returns the current {@code interestOps} of this channel.
    306      *
    307      * @return {@link #OP_NONE}, {@link #OP_READ}, {@link #OP_WRITE}, or
    308      *         {@link #OP_READ_WRITE}
    309      */
    310     int getInterestOps();
    311
    312     /**
    313      * Returns {@code true} if and only if the I/O thread will read a message
    314      * from this channel.  This method is a shortcut to the following code:
    315      * <pre>
    316      * return (getInterestOps() & OP_READ) != 0;
    317      * </pre>
    318      */
    319     boolean isReadable();
    320
    321     /**
    322      * Returns {@code true} if and only if the I/O thread will perform the
    323      * requested write operation immediately.  Any write requests made when
    324      * this method returns {@code false} are queued until the I/O thread is
    325      * ready to process the queued write requests.  This method is a shortcut
    326      * to the following code:
    327      * <pre>
    328      * return (getInterestOps() & OP_WRITE) == 0;
    329      * </pre>
    330      */
    331     boolean isWritable();
    332
    333     /**
    334      * Changes the {@code interestOps} of this channel asynchronously.
    335      *
    336      * @param interestOps the new {@code interestOps}
    337      *
    338      * @return the {@link ChannelFuture} which will be notified when the
    339      *         {@code interestOps} change request succeeds or fails
    340      */
    341     ChannelFuture setInterestOps(int interestOps);
    342
    343     /**
    344      * Suspends or resumes the read operation of the I/O thread asynchronously.
    345      * This method is a shortcut to the following code:
    346      * <pre>
    347      * int interestOps = getInterestOps();
    348      * if (readable) {
    349      *     setInterestOps(interestOps | OP_READ);
    350      * } else {
    351      *     setInterestOps(interestOps & ~OP_READ);
    352      * }
    353      * </pre>
    354      *
    355      * @param readable {@code true} to resume the read operation and
    356      *                 {@code false} to suspend the read operation
    357      *
    358      * @return the {@link ChannelFuture} which will be notified when the
    359      *         {@code interestOps} change request succeeds or fails
    360      */
    361     ChannelFuture setReadable(boolean readable);
    362
    363     /**
    364      * Retrieves an object which is {@link #setAttachment(Object) attached} to
    365      * this {@link Channel}.
    366      *
    367      * @return {@code null} if no object was attached or {@code null} was
    368      *         attached
    369      */
    370     Object getAttachment();
    371
    372     /**
    373      * Attaches an object to this {@link Channel} to store a stateful
    374      * information
    375      */
    376     void setAttachment(Object attachment);
    377 }