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