1 /* 2 * Copyright 2009 Red Hat, Inc. 3 * 4 * Red Hat licenses this file to you under the Apache License, version 2.0 5 * (the "License"); you may not use this file except in compliance with the 6 * 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 * @author <a href="http://www.jboss.org/netty/">The Netty Project</a> 104 * @author <a href="http://gleamynode.net/">Trustin Lee</a> 105 * 106 * @version $Rev: 2244 $, $Date: 2010-04-16 14:07:37 +0900 (Fri, 16 Apr 2010) $ 107 * 108 * @apiviz.landmark 109 * @apiviz.composedOf org.jboss.netty.channel.ChannelConfig 110 * @apiviz.composedOf org.jboss.netty.channel.ChannelPipeline 111 * 112 * @apiviz.exclude ^org\.jboss\.netty\.channel\.([a-z]+\.)+[^\.]+Channel$ 113 */ 114 public interface Channel extends Comparable<Channel> { 115 116 /** 117 * The {@link #getInterestOps() interestOps} value which tells that only 118 * read operation has been suspended. 119 */ 120 static int OP_NONE = 0; 121 122 /** 123 * The {@link #getInterestOps() interestOps} value which tells that neither 124 * read nor write operation has been suspended. 125 */ 126 static int OP_READ = 1; 127 128 /** 129 * The {@link #getInterestOps() interestOps} value which tells that both 130 * read and write operation has been suspended. 131 */ 132 static int OP_WRITE = 4; 133 134 /** 135 * The {@link #getInterestOps() interestOps} value which tells that only 136 * write operation has been suspended. 137 */ 138 static int OP_READ_WRITE = OP_READ | OP_WRITE; 139 140 /** 141 * Returns the unique integer ID of this channel. 142 */ 143 Integer getId(); 144 145 /** 146 * Returns the {@link ChannelFactory} which created this channel. 147 */ 148 ChannelFactory getFactory(); 149 150 /** 151 * Returns the parent of this channel. 152 * 153 * @return the parent channel. 154 * {@code null} if this channel does not have a parent channel. 155 */ 156 Channel getParent(); 157 158 /** 159 * Returns the configuration of this channel. 160 */ 161 ChannelConfig getConfig(); 162 163 /** 164 * Returns the {@link ChannelPipeline} which handles {@link ChannelEvent}s 165 * associated with this channel. 166 */ 167 ChannelPipeline getPipeline(); 168 169 /** 170 * Returns {@code true} if and only if this channel is open. 171 */ 172 boolean isOpen(); 173 174 /** 175 * Returns {@code true} if and only if this channel is bound to a 176 * {@linkplain #getLocalAddress() local address}. 177 */ 178 boolean isBound(); 179 180 /** 181 * Returns {@code true} if and only if this channel is connected to a 182 * {@linkplain #getRemoteAddress() remote address}. 183 */ 184 boolean isConnected(); 185 186 /** 187 * Returns the local address where this channel is bound to. The returned 188 * {@link SocketAddress} is supposed to be down-cast into more concrete 189 * type such as {@link InetSocketAddress} to retrieve the detailed 190 * information. 191 * 192 * @return the local address of this channel. 193 * {@code null} if this channel is not bound. 194 */ 195 SocketAddress getLocalAddress(); 196 197 /** 198 * Returns the remote address where this channel is connected to. The 199 * returned {@link SocketAddress} is supposed to be down-cast into more 200 * concrete type such as {@link InetSocketAddress} to retrieve the detailed 201 * information. 202 * 203 * @return the remote address of this channel. 204 * {@code null} if this channel is not connected. 205 * If this channel is not connected but it can receive messages 206 * from arbitrary remote addresses (e.g. {@link DatagramChannel}, 207 * use {@link MessageEvent#getRemoteAddress()} to determine 208 * the origination of the received message as this method will 209 * return {@code null}. 210 */ 211 SocketAddress getRemoteAddress(); 212 213 /** 214 * Sends a message to this channel asynchronously. If this channel was 215 * created by a connectionless transport (e.g. {@link DatagramChannel}) 216 * and is not connected yet, you have to call {@link #write(Object, SocketAddress)} 217 * instead. Otherwise, the write request will fail with 218 * {@link NotYetConnectedException} and an {@code 'exceptionCaught'} event 219 * will be triggered. 220 * 221 * @param message the message to write 222 * 223 * @return the {@link ChannelFuture} which will be notified when the 224 * write request succeeds or fails 225 * 226 * @throws NullPointerException if the specified message is {@code null} 227 */ 228 ChannelFuture write(Object message); 229 230 /** 231 * Sends a message to this channel asynchronously. It has an additional 232 * parameter that allows a user to specify where to send the specified 233 * message instead of this channel's current remote address. If this 234 * channel was created by a connectionless transport (e.g. {@link DatagramChannel}) 235 * and is not connected yet, you must specify non-null address. Otherwise, 236 * the write request will fail with {@link NotYetConnectedException} and 237 * an {@code 'exceptionCaught'} event will be triggered. 238 * 239 * @param message the message to write 240 * @param remoteAddress where to send the specified message. 241 * This method is identical to {@link #write(Object)} 242 * if {@code null} is specified here. 243 * 244 * @return the {@link ChannelFuture} which will be notified when the 245 * write request succeeds or fails 246 * 247 * @throws NullPointerException if the specified message is {@code null} 248 */ 249 ChannelFuture write(Object message, SocketAddress remoteAddress); 250 251 /** 252 * Binds this channel to the specified local address asynchronously. 253 * 254 * @param localAddress where to bind 255 * 256 * @return the {@link ChannelFuture} which will be notified when the 257 * bind request succeeds or fails 258 * 259 * @throws NullPointerException if the specified address is {@code null} 260 */ 261 ChannelFuture bind(SocketAddress localAddress); 262 263 /** 264 * Connects this channel to the specified remote address asynchronously. 265 * 266 * @param remoteAddress where to connect 267 * 268 * @return the {@link ChannelFuture} which will be notified when the 269 * connection request succeeds or fails 270 * 271 * @throws NullPointerException if the specified address is {@code null} 272 */ 273 ChannelFuture connect(SocketAddress remoteAddress); 274 275 /** 276 * Disconnects this channel from the current remote address asynchronously. 277 * 278 * @return the {@link ChannelFuture} which will be notified when the 279 * disconnection request succeeds or fails 280 */ 281 ChannelFuture disconnect(); 282 283 /** 284 * Unbinds this channel from the current local address asynchronously. 285 * 286 * @return the {@link ChannelFuture} which will be notified when the 287 * unbind request succeeds or fails 288 */ 289 ChannelFuture unbind(); 290 291 /** 292 * Closes this channel asynchronously. If this channel is bound or 293 * connected, it will be disconnected and unbound first. Once a channel 294 * is closed, it can not be open again. Calling this method on a closed 295 * channel has no effect. Please note that this method always returns the 296 * same future instance. 297 * 298 * @return the {@link ChannelFuture} which will be notified when the 299 * close request succeeds or fails 300 */ 301 ChannelFuture close(); 302 303 /** 304 * Returns the {@link ChannelFuture} which will be notified when this 305 * channel is closed. This method always returns the same future instance. 306 */ 307 ChannelFuture getCloseFuture(); 308 309 /** 310 * Returns the current {@code interestOps} of this channel. 311 * 312 * @return {@link #OP_NONE}, {@link #OP_READ}, {@link #OP_WRITE}, or 313 * {@link #OP_READ_WRITE} 314 */ 315 int getInterestOps(); 316 317 /** 318 * Returns {@code true} if and only if the I/O thread will read a message 319 * from this channel. This method is a shortcut to the following code: 320 * <pre> 321 * return (getInterestOps() & OP_READ) != 0; 322 * </pre> 323 */ 324 boolean isReadable(); 325 326 /** 327 * Returns {@code true} if and only if the I/O thread will perform the 328 * requested write operation immediately. Any write requests made when 329 * this method returns {@code false} are queued until the I/O thread is 330 * ready to process the queued write requests. This method is a shortcut 331 * to the following code: 332 * <pre> 333 * return (getInterestOps() & OP_WRITE) == 0; 334 * </pre> 335 */ 336 boolean isWritable(); 337 338 /** 339 * Changes the {@code interestOps} of this channel asynchronously. 340 * 341 * @param interestOps the new {@code interestOps} 342 * 343 * @return the {@link ChannelFuture} which will be notified when the 344 * {@code interestOps} change request succeeds or fails 345 */ 346 ChannelFuture setInterestOps(int interestOps); 347 348 /** 349 * Suspends or resumes the read operation of the I/O thread asynchronously. 350 * This method is a shortcut to the following code: 351 * <pre> 352 * int interestOps = getInterestOps(); 353 * if (readable) { 354 * setInterestOps(interestOps | OP_READ); 355 * } else { 356 * setInterestOps(interestOps & ~OP_READ); 357 * } 358 * </pre> 359 * 360 * @param readable {@code true} to resume the read operation and 361 * {@code false} to suspend the read operation 362 * 363 * @return the {@link ChannelFuture} which will be notified when the 364 * {@code interestOps} change request succeeds or fails 365 */ 366 ChannelFuture setReadable(boolean readable); 367 }