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 * Returns {@code true} if and only if the user-defined writability flag at the specified index is set to
365 * {@code true}.
366 */
367 boolean getUserDefinedWritability(int index);
368
369 /**
370 * Sets a user-defined writability flag at the specified index.
371 */
372 void setUserDefinedWritability(int index, boolean isWritable);
373
374 /**
375 * Retrieves an object which is {@link #setAttachment(Object) attached} to
376 * this {@link Channel}.
377 *
378 * @return {@code null} if no object was attached or {@code null} was
379 * attached
380 */
381 Object getAttachment();
382
383 /**
384 * Attaches an object to this {@link Channel} to store a stateful
385 * information
386 */
387 void setAttachment(Object attachment);
388 }