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 io.netty.channel;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.buffer.ByteBufAllocator;
20  import io.netty.util.AttributeKey;
21  import io.netty.util.AttributeMap;
22  import io.netty.util.concurrent.EventExecutor;
23  import io.netty.util.concurrent.FutureListener;
24  
25  import java.net.ConnectException;
26  import java.net.SocketAddress;
27  import java.nio.channels.Channels;
28  
29  /**
30   * Enables a [email protected] ChannelHandler} to interact with its [email protected] ChannelPipeline}
31   * and other handlers. Among other things a handler can notify the next [email protected] ChannelHandler} in the
32   * [email protected] ChannelPipeline} as well as modify the [email protected] ChannelPipeline} it belongs to dynamically.
33   *
34   * <h3>Notify</h3>
35   *
36   * You can notify the closest handler in the same [email protected] ChannelPipeline} by calling one of the various methods
37   * provided here.
38   *
39   * Please refer to [email protected] ChannelPipeline} to understand how an event flows.
40   *
41   * <h3>Modifying a pipeline</h3>
42   *
43   * You can get the [email protected] ChannelPipeline} your handler belongs to by calling
44   * [email protected] #pipeline()}.  A non-trivial application could insert, remove, or
45   * replace handlers in the pipeline dynamically at runtime.
46   *
47   * <h3>Retrieving for later use</h3>
48   *
49   * You can keep the [email protected] ChannelHandlerContext} for later use, such as
50   * triggering an event outside the handler methods, even from a different thread.
51   * <pre>
52   * public class MyHandler extends [email protected] ChannelDuplexHandler} {
53   *
54   *     <b>private [email protected] ChannelHandlerContext} ctx;</b>
55   *
56   *     public void beforeAdd([email protected] ChannelHandlerContext} ctx) {
57   *         <b>this.ctx = ctx;</b>
58   *     }
59   *
60   *     public void login(String username, password) {
61   *         ctx.write(new LoginMessage(username, password));
62   *     }
63   *     ...
64   * }
65   * </pre>
66   *
67   * <h3>Storing stateful information</h3>
68   *
69   * [email protected] #attr(AttributeKey)} allow you to
70   * store and access stateful information that is related with a handler and its
71   * context.  Please refer to [email protected] ChannelHandler} to learn various recommended
72   * ways to manage stateful information.
73   *
74   * <h3>A handler can have more than one context</h3>
75   *
76   * Please note that a [email protected] ChannelHandler} instance can be added to more than
77   * one [email protected] ChannelPipeline}.  It means a single [email protected] ChannelHandler}
78   * instance can have more than one [email protected] ChannelHandlerContext} and therefore
79   * the single instance can be invoked with different
80   * [email protected] ChannelHandlerContext}s if it is added to one or more
81   * [email protected] ChannelPipeline}s more than once.
82   * <p>
83   * For example, the following handler will have as many independent [email protected] AttributeKey}s
84   * as how many times it is added to pipelines, regardless if it is added to the
85   * same pipeline multiple times or added to different pipelines multiple times:
86   * <pre>
87   * public class FactorialHandler extends [email protected] ChannelInboundHandlerAdapter} {
88   *
89   *   private final [email protected] AttributeKey}&lt;[email protected] Integer}&gt; counter = [email protected] AttributeKey}.valueOf("counter");
90   *
91   *   // This handler will receive a sequence of increasing integers starting
92   *   // from 1.
93   *   [email protected] @Override}
94   *   public void channelRead([email protected] ChannelHandlerContext} ctx, Object msg) {
95   *     Integer a = ctx.attr(counter).get();
96   *
97   *     if (a == null) {
98   *       a = 1;
99   *     }
100  *
101  *     attr.set(a * (Integer) msg);
102  *   }
103  * }
104  *
105  * // Different context objects are given to "f1", "f2", "f3", and "f4" even if
106  * // they refer to the same handler instance.  Because the FactorialHandler
107  * // stores its state in a context object (using an [email protected] AttributeKey}), the factorial is
108  * // calculated correctly 4 times once the two pipelines (p1 and p2) are active.
109  * FactorialHandler fh = new FactorialHandler();
110  *
111  * [email protected] ChannelPipeline} p1 = [email protected] Channels}.pipeline();
112  * p1.addLast("f1", fh);
113  * p1.addLast("f2", fh);
114  *
115  * [email protected] ChannelPipeline} p2 = [email protected] Channels}.pipeline();
116  * p2.addLast("f3", fh);
117  * p2.addLast("f4", fh);
118  * </pre>
119  *
120  * <h3>Additional resources worth reading</h3>
121  * <p>
122  * Please refer to the [email protected] ChannelHandler}, and
123  * [email protected] ChannelPipeline} to find out more about inbound and outbound operations,
124  * what fundamental differences they have, how they flow in a  pipeline,  and how to handle
125  * the operation in your application.
126  */
127 public interface ChannelHandlerContext extends AttributeMap {
128 
129     /**
130      * Return the [email protected] Channel} which is bound to the [email protected] ChannelHandlerContext}.
131      */
132     Channel channel();
133 
134     /**
135      * Returns the [email protected] EventExecutor} which is used to execute an arbitrary task.
136      */
137     EventExecutor executor();
138 
139     /**
140      * Returns the [email protected] ChannelHandlerInvoker} which is used to trigger an event for the associated
141      * [email protected] ChannelHandler}. Note that the methods in [email protected] ChannelHandlerInvoker} are not intended to be called
142      * by a user. Use this method only to obtain the reference to the [email protected] ChannelHandlerInvoker}
143      * (and not calling its methods) unless you know what you are doing.
144      */
145     ChannelHandlerInvoker invoker();
146 
147     /**
148      * The unique name of the [email protected] ChannelHandlerContext}.The name was used when then [email protected] ChannelHandler}
149      * was added to the [email protected] ChannelPipeline}. This name can also be used to access the registered
150      * [email protected] ChannelHandler} from the [email protected] ChannelPipeline}.
151      */
152     String name();
153 
154     /**
155      * The [email protected] ChannelHandler} that is bound this [email protected] ChannelHandlerContext}.
156      */
157     ChannelHandler handler();
158 
159     /**
160      * Return [email protected] true} if the [email protected] ChannelHandler} which belongs to this context was removed
161      * from the [email protected] ChannelPipeline}. Note that this method is only meant to be called from with in the
162      * [email protected] EventLoop}.
163      */
164     boolean isRemoved();
165 
166     /**
167      * A [email protected] Channel} was registered to its [email protected] EventLoop}.
168      *
169      * This will result in having the [email protected] ChannelInboundHandler#channelRegistered(ChannelHandlerContext)} method
170      * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
171      * [email protected] Channel}.
172      */
173     ChannelHandlerContext fireChannelRegistered();
174 
175     /**
176      * A [email protected] Channel} was unregistered from its [email protected] EventLoop}.
177      *
178      * This will result in having the [email protected] ChannelInboundHandler#channelUnregistered(ChannelHandlerContext)} method
179      * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
180      * [email protected] Channel}.
181      */
182     ChannelHandlerContext fireChannelUnregistered();
183 
184     /**
185      * A [email protected] Channel} is active now, which means it is connected.
186      *
187      * This will result in having the [email protected] ChannelInboundHandler#channelActive(ChannelHandlerContext)} method
188      * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
189      * [email protected] Channel}.
190      */
191     ChannelHandlerContext fireChannelActive();
192 
193     /**
194      * A [email protected] Channel} is inactive now, which means it is closed.
195      *
196      * This will result in having the [email protected] ChannelInboundHandler#channelInactive(ChannelHandlerContext)} method
197      * called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
198      * [email protected] Channel}.
199      */
200     ChannelHandlerContext fireChannelInactive();
201 
202     /**
203      * A [email protected] Channel} received an [email protected] Throwable} in one of its inbound operations.
204      *
205      * This will result in having the [email protected] ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)}
206      * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
207      * [email protected] Channel}.
208      */
209     ChannelHandlerContext fireExceptionCaught(Throwable cause);
210 
211     /**
212      * A [email protected] Channel} received an user defined event.
213      *
214      * This will result in having the [email protected] ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)}
215      * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
216      * [email protected] Channel}.
217      */
218     ChannelHandlerContext fireUserEventTriggered(Object event);
219 
220     /**
221      * A [email protected] Channel} received a message.
222      *
223      * This will result in having the [email protected] ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)}
224      * method called of the next [email protected] ChannelInboundHandler} contained in the [email protected] ChannelPipeline} of the
225      * [email protected] Channel}.
226      */
227     ChannelHandlerContext fireChannelRead(Object msg);
228 
229     /**
230      * Triggers an [email protected] ChannelInboundHandler#channelReadComplete(ChannelHandlerContext)}
231      * event to the next [email protected] ChannelInboundHandler} in the [email protected] ChannelPipeline}.
232      */
233     ChannelHandlerContext fireChannelReadComplete();
234 
235     /**
236      * Triggers an [email protected] ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)}
237      * event to the next [email protected] ChannelInboundHandler} in the [email protected] ChannelPipeline}.
238      */
239     ChannelHandlerContext fireChannelWritabilityChanged();
240 
241     /**
242      * Request to bind to the given [email protected] SocketAddress} and notify the [email protected] ChannelFuture} once the operation
243      * completes, either because the operation was successful or because of an error.
244      * <p>
245      * This will result in having the
246      * [email protected] ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
247      * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
248      * {@link Channel}.
249      */
250     ChannelFuture bind(SocketAddress localAddress);
251 
252     /**
253      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
254      * completes, either because the operation was successful or because of an error.
255      * <p>
256      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
257      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
258      * will be used.
259      * <p>
260      * This will result in having the
261      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
262      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
263      * {@link Channel}.
264      */
265     ChannelFuture connect(SocketAddress remoteAddress);
266 
267     /**
268      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
269      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
270      * an error.
271      * <p>
272      * This will result in having the
273      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
274      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
275      * {@link Channel}.
276      */
277     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
278 
279     /**
280      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
281      * either because the operation was successful or because of an error.
282      * <p>
283      * This will result in having the
284      * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
285      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
286      * {@link Channel}.
287      */
288     ChannelFuture disconnect();
289 
290     /**
291      * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
292      * either because the operation was successful or because of
293      * an error.
294      *
295      * After it is closed it is not possible to reuse it again.
296      * <p>
297      * This will result in having the
298      * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
299      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
300      * {@link Channel}.
301      */
302     ChannelFuture close();
303 
304     /**
305      * Request to deregister from the previous assigned {@link EventExecutor} and notify the
306      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
307      * an error.
308      * <p>
309      * This will result in having the
310      * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
311      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
312      * {@link Channel}.
313      *
314      */
315     ChannelFuture deregister();
316 
317     /**
318      * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
319      * completes, either because the operation was successful or because of an error.
320      *
321      * The given {@link ChannelPromise} will be notified.
322      * <p>
323      * This will result in having the
324      * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
325      * called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
326      * {@link Channel}.
327      */
328     ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
329 
330     /**
331      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
332      * completes, either because the operation was successful or because of an error.
333      *
334      * The given {@link ChannelFuture} will be notified.
335      *
336      * <p>
337      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
338      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
339      * will be used.
340      * <p>
341      * This will result in having the
342      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
343      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
344      * {@link Channel}.
345      */
346     ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
347 
348     /**
349      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
350      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
351      * an error.
352      *
353      * The given {@link ChannelPromise} will be notified and also returned.
354      * <p>
355      * This will result in having the
356      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
357      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
358      * {@link Channel}.
359      */
360     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
361 
362     /**
363      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
364      * either because the operation was successful or because of an error.
365      *
366      * The given {@link ChannelPromise} will be notified.
367      * <p>
368      * This will result in having the
369      * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
370      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
371      * {@link Channel}.
372      */
373     ChannelFuture disconnect(ChannelPromise promise);
374 
375     /**
376      * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
377      * either because the operation was successful or because of
378      * an error.
379      *
380      * After it is closed it is not possible to reuse it again.
381      * The given {@link ChannelPromise} will be notified.
382      * <p>
383      * This will result in having the
384      * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
385      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
386      * {@link Channel}.
387      */
388     ChannelFuture close(ChannelPromise promise);
389 
390     /**
391      * Request to deregister from the previous assigned {@link EventExecutor} and notify the
392      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
393      * an error.
394      *
395      * The given {@link ChannelPromise} will be notified.
396      * <p>
397      * This will result in having the
398      * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
399      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
400      * {@link Channel}.
401      */
402     ChannelFuture deregister(ChannelPromise promise);
403 
404     /**
405      * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
406      * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was
407      * read, and triggers a
408      * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the
409      * handler can decide to continue reading.  If there's a pending read operation already, this method does nothing.
410      * <p>
411      * This will result in having the
412      * {@link ChannelOutboundHandler#read(ChannelHandlerContext)}
413      * method called of the next {@link ChannelOutboundHandler} contained in the {@link ChannelPipeline} of the
414      * {@link Channel}.
415      */
416     ChannelHandlerContext read();
417 
418     /**
419      * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
420      * This method will not request to actual flush, so be sure to call {@link #flush()}
421      * once you want to request to flush all pending data to the actual transport.
422      */
423     ChannelFuture write(Object msg);
424 
425     /**
426      * Request to write a message via this {@link ChannelHandlerContext} through the {@link ChannelPipeline}.
427      * This method will not request to actual flush, so be sure to call {@link #flush()}
428      * once you want to request to flush all pending data to the actual transport.
429      */
430     ChannelFuture write(Object msg, ChannelPromise promise);
431 
432     /**
433      * Request to flush all pending messages via this ChannelOutboundInvoker.
434      */
435     ChannelHandlerContext flush();
436 
437     /**
438      * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}.
439      */
440     ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
441 
442     /**
443      * Shortcut for call {@link #write(Object)} and {@link #flush()}.
444      */
445     ChannelFuture writeAndFlush(Object msg);
446 
447     /**
448      * Return the assigned {@link ChannelPipeline}
449      */
450     ChannelPipeline pipeline();
451 
452     /**
453      * Return the assigned {@link ByteBufAllocator} which will be used to allocate {@link ByteBuf}s.
454      */
455     ByteBufAllocator alloc();
456 
457     /**
458      * Return a new {@link ChannelPromise}.
459      */
460     ChannelPromise newPromise();
461 
462     /**
463      * Return an new {@link ChannelProgressivePromise}
464      */
465     ChannelProgressivePromise newProgressivePromise();
466 
467     /**
468      * Create a new {@link ChannelFuture} which is marked as succeeded already. So {@link ChannelFuture#isSuccess()}
469      * will return {@code true}. All {@link FutureListener} added to it will be notified directly. Also
470      * every call of blocking methods will just return without blocking.
471      */
472     ChannelFuture newSucceededFuture();
473 
474     /**
475      * Create a new {@link ChannelFuture} which is marked as failed already. So {@link ChannelFuture#isSuccess()}
476      * will return {@code false}. All {@link FutureListener} added to it will be notified directly. Also
477      * every call of blocking methods will just return without blocking.
478      */
479     ChannelFuture newFailedFuture(Throwable cause);
480 
481     /**
482      * Return a special ChannelPromise which can be reused for different operations.
483      * <p>
484      * It's only supported to use
485      * it for {@link ChannelHandlerContext#write(Object, ChannelPromise)}.
486      * </p>
487      * <p>
488      * Be aware that the returned {@link ChannelPromise} will not support most operations and should only be used
489      * if you want to save an object allocation for every write operation. You will not be able to detect if the
490      * operation  was complete, only if it failed as the implementation will call
491      * {@link ChannelPipeline#fireExceptionCaught(Throwable)} in this case.
492      * </p>
493      * <strong>Be aware this is an expert feature and should be used with care!</strong>
494      */
495     ChannelPromise voidPromise();
496 
497 }