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 }