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.util.concurrent.DefaultEventExecutorGroup;
20  import io.netty.util.concurrent.EventExecutor;
21  import io.netty.util.concurrent.EventExecutorGroup;
22  
23  import java.net.ConnectException;
24  import java.net.SocketAddress;
25  import java.nio.ByteBuffer;
26  import java.nio.channels.SocketChannel;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Map.Entry;
30  import java.util.NoSuchElementException;
31  
32  
33  /**
34   * A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a
35   * {@link Channel}.  {@link ChannelPipeline} implements an advanced form of the
36   * <a href="http://www.oracle.com/technetwork/java/interceptingfilter-142169.html">Intercepting Filter</a> pattern
37   * to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline
38   * interact with each other.
39   *
40   * <h3>Creation of a pipeline</h3>
41   *
42   * Each channel has its own pipeline and it is created automatically when a new channel is created.
43   *
44   * <h3>How an event flows in a pipeline</h3>
45   *
46   * The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline}
47   * typically. An I/O event is handled by either a {@link ChannelInboundHandler} or a {@link ChannelOutboundHandler}
48   * and be forwarded to its closest handler by calling the event propagation methods defined in
49   * {@link ChannelHandlerContext}, such as {@link ChannelHandlerContext#fireChannelRead(Object)} and
50   * {@link ChannelHandlerContext#write(Object)}.
51   *
52   * <pre>
53   *                                                 I/O Request
54   *                                            via {@link Channel} or
55   *                                        {@link ChannelHandlerContext}
56   *                                                      |
57   *  +---------------------------------------------------+---------------+
58   *  |                           ChannelPipeline         |               |
59   *  |                                                  \|/              |
60   *  |    +---------------------+            +-----------+----------+    |
61   *  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
62   *  |    +----------+----------+            +-----------+----------+    |
63   *  |              /|\                                  |               |
64   *  |               |                                  \|/              |
65   *  |    +----------+----------+            +-----------+----------+    |
66   *  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
67   *  |    +----------+----------+            +-----------+----------+    |
68   *  |              /|\                                  .               |
69   *  |               .                                   .               |
70   *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
71   *  |        [ method call]                       [method call]         |
72   *  |               .                                   .               |
73   *  |               .                                  \|/              |
74   *  |    +----------+----------+            +-----------+----------+    |
75   *  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
76   *  |    +----------+----------+            +-----------+----------+    |
77   *  |              /|\                                  |               |
78   *  |               |                                  \|/              |
79   *  |    +----------+----------+            +-----------+----------+    |
80   *  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
81   *  |    +----------+----------+            +-----------+----------+    |
82   *  |              /|\                                  |               |
83   *  +---------------+-----------------------------------+---------------+
84   *                  |                                  \|/
85   *  +---------------+-----------------------------------+---------------+
86   *  |               |                                   |               |
87   *  |       [ Socket.read() ]                    [ Socket.write() ]     |
88   *  |                                                                   |
89   *  |  Netty Internal I/O Threads (Transport Implementation)            |
90   *  +-------------------------------------------------------------------+
91   * </pre>
92   * An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the
93   * diagram.  An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the
94   * diagram.  The inbound data is often read from a remote peer via the actual input operation such as
95   * {@link SocketChannel#read(ByteBuffer)}.  If an inbound event goes beyond the top inbound handler, it is discarded
96   * silently, or logged if it needs your attention.
97   * <p>
98   * An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the
99   * diagram.  An outbound handler usually generates or transforms the outbound traffic such as write requests.
100  * If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the
101  * {@link Channel}. The I/O thread often performs the actual output operation such as
102  * {@link SocketChannel#write(ByteBuffer)}.
103  * <p>
104  * For example, let us assume that we created the following pipeline:
105  * <pre>
106  * {@link ChannelPipeline} p = ...;
107  * p.addLast("1", new InboundHandlerA());
108  * p.addLast("2", new InboundHandlerB());
109  * p.addLast("3", new OutboundHandlerA());
110  * p.addLast("4", new OutboundHandlerB());
111  * p.addLast("5", new InboundOutboundHandlerX());
112  * </pre>
113  * In the example above, the class whose name starts with {@code Inbound} means it is an inbound handler.
114  * The class whose name starts with {@code Outbound} means it is a outbound handler.
115  * <p>
116  * In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound.
117  * When an event goes outbound, the order is 5, 4, 3, 2, 1.  On top of this principle, {@link ChannelPipeline} skips
118  * the evaluation of certain handlers to shorten the stack depth:
119  * <ul>
120  * <li>3 and 4 don't implement {@link ChannelInboundHandler}, and therefore the actual evaluation order of an inbound
121  *     event will be: 1, 2, and 5.</li>
122  * <li>1 and 2 don't implement {@link ChannelOutboundHandler}, and therefore the actual evaluation order of a
123  *     outbound event will be: 5, 4, and 3.</li>
124  * <li>If 5 implements both {@link ChannelInboundHandler} and {@link ChannelOutboundHandler}, the evaluation order of
125  *     an inbound and a outbound event could be 125 and 543 respectively.</li>
126  * </ul>
127  *
128  * <h3>Forwarding an event to the next handler</h3>
129  *
130  * As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in
131  * {@link ChannelHandlerContext} to forward an event to its next handler.  Those methods include:
132  * <ul>
133  * <li>Inbound event propagation methods:
134  *     <ul>
135  *     <li>{@link ChannelHandlerContext#fireChannelRegistered()}</li>
136  *     <li>{@link ChannelHandlerContext#fireChannelActive()}</li>
137  *     <li>{@link ChannelHandlerContext#fireChannelRead(Object)}</li>
138  *     <li>{@link ChannelHandlerContext#fireChannelReadComplete()}</li>
139  *     <li>{@link ChannelHandlerContext#fireExceptionCaught(Throwable)}</li>
140  *     <li>{@link ChannelHandlerContext#fireUserEventTriggered(Object)}</li>
141  *     <li>{@link ChannelHandlerContext#fireChannelWritabilityChanged()}</li>
142  *     <li>{@link ChannelHandlerContext#fireChannelInactive()}</li>
143  *     <li>{@link ChannelHandlerContext#fireChannelUnregistered()}</li>
144  *     </ul>
145  * </li>
146  * <li>Outbound event propagation methods:
147  *     <ul>
148  *     <li>{@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}</li>
149  *     <li>{@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}</li>
150  *     <li>{@link ChannelHandlerContext#write(Object, ChannelPromise)}</li>
151  *     <li>{@link ChannelHandlerContext#flush()}</li>
152  *     <li>{@link ChannelHandlerContext#read()}</li>
153  *     <li>{@link ChannelHandlerContext#disconnect(ChannelPromise)}</li>
154  *     <li>{@link ChannelHandlerContext#close(ChannelPromise)}</li>
155  *     <li>{@link ChannelHandlerContext#deregister(ChannelPromise)}</li>
156  *     </ul>
157  * </li>
158  * </ul>
159  *
160  * and the following example shows how the event propagation is usually done:
161  *
162  * <pre>
163  * public class MyInboundHandler extends {@link ChannelInboundHandlerAdapter} {
164  *     {@code @Override}
165  *     public void channelActive({@link ChannelHandlerContext} ctx) {
166  *         System.out.println("Connected!");
167  *         ctx.fireChannelActive();
168  *     }
169  * }
170  *
171  * public class MyOutboundHandler extends {@link ChannelOutboundHandlerAdapter} {
172  *     {@code @Override}
173  *     public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
174  *         System.out.println("Closing ..");
175  *         ctx.close(promise);
176  *     }
177  * }
178  * </pre>
179  *
180  * <h3>Building a pipeline</h3>
181  * <p>
182  * A user is supposed to have one or more {@link ChannelHandler}s in a pipeline to receive I/O events (e.g. read) and
183  * to request I/O operations (e.g. write and close).  For example, a typical server will have the following handlers
184  * in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the
185  * protocol and business logic:
186  *
187  * <ol>
188  * <li>Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.</li>
189  * <li>Protocol Encoder - translates a Java object into binary data.</li>
190  * <li>Business Logic Handler - performs the actual business logic (e.g. database access).</li>
191  * </ol>
192  *
193  * and it could be represented as shown in the following example:
194  *
195  * <pre>
196  * static final {@link EventExecutorGroup} group = new {@link DefaultEventExecutorGroup}(16);
197  * ...
198  *
199  * {@link ChannelPipeline} pipeline = ch.pipeline();
200  *
201  * pipeline.addLast("decoder", new MyProtocolDecoder());
202  * pipeline.addLast("encoder", new MyProtocolEncoder());
203  *
204  * // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
205  * // in a different thread than an I/O thread so that the I/O thread is not blocked by
206  * // a time-consuming task.
207  * // If your business logic is fully asynchronous or finished very quickly, you don't
208  * // need to specify a group.
209  * pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
210  * </pre>
211  *
212  * <h3>Thread safety</h3>
213  * <p>
214  * A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe.
215  * For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
216  * after the exchange.
217  */
218 public interface ChannelPipeline
219          extends Iterable<Entry<String, ChannelHandler>> {
220 
221     /**
222      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
223      *
224      * @param name     the name of the handler to insert first
225      * @param handler  the handler to insert first
226      *
227      * @throws IllegalArgumentException
228      *         if there's an entry with the same name already in the pipeline
229      * @throws NullPointerException
230      *         if the specified handler is {@code null}
231      */
232     ChannelPipeline addFirst(String name, ChannelHandler handler);
233 
234     /**
235      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
236      *
237      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
238      *                 methods
239      * @param name     the name of the handler to insert first
240      * @param handler  the handler to insert first
241      *
242      * @throws IllegalArgumentException
243      *         if there's an entry with the same name already in the pipeline
244      * @throws NullPointerException
245      *         if the specified handler is {@code null}
246      */
247     ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
248 
249     /**
250      * Appends a {@link ChannelHandler} at the last position of this pipeline.
251      *
252      * @param name     the name of the handler to append
253      * @param handler  the handler to append
254      *
255      * @throws IllegalArgumentException
256      *         if there's an entry with the same name already in the pipeline
257      * @throws NullPointerException
258      *         if the specified handler is {@code null}
259      */
260     ChannelPipeline addLast(String name, ChannelHandler handler);
261 
262     /**
263      * Appends a {@link ChannelHandler} at the last position of this pipeline.
264      *
265      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
266      *                 methods
267      * @param name     the name of the handler to append
268      * @param handler  the handler to append
269      *
270      * @throws IllegalArgumentException
271      *         if there's an entry with the same name already in the pipeline
272      * @throws NullPointerException
273      *         if the specified handler is {@code null}
274      */
275     ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
276 
277     /**
278      * Inserts a {@link ChannelHandler} before an existing handler of this
279      * pipeline.
280      *
281      * @param baseName  the name of the existing handler
282      * @param name      the name of the handler to insert before
283      * @param handler   the handler to insert before
284      *
285      * @throws NoSuchElementException
286      *         if there's no such entry with the specified {@code baseName}
287      * @throws IllegalArgumentException
288      *         if there's an entry with the same name already in the pipeline
289      * @throws NullPointerException
290      *         if the specified baseName or handler is {@code null}
291      */
292     ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
293 
294     /**
295      * Inserts a {@link ChannelHandler} before an existing handler of this
296      * pipeline.
297      *
298      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
299      *                  methods
300      * @param baseName  the name of the existing handler
301      * @param name      the name of the handler to insert before
302      * @param handler   the handler to insert before
303      *
304      * @throws NoSuchElementException
305      *         if there's no such entry with the specified {@code baseName}
306      * @throws IllegalArgumentException
307      *         if there's an entry with the same name already in the pipeline
308      * @throws NullPointerException
309      *         if the specified baseName or handler is {@code null}
310      */
311     ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
312 
313     /**
314      * Inserts a {@link ChannelHandler} after an existing handler of this
315      * pipeline.
316      *
317      * @param baseName  the name of the existing handler
318      * @param name      the name of the handler to insert after
319      * @param handler   the handler to insert after
320      *
321      * @throws NoSuchElementException
322      *         if there's no such entry with the specified {@code baseName}
323      * @throws IllegalArgumentException
324      *         if there's an entry with the same name already in the pipeline
325      * @throws NullPointerException
326      *         if the specified baseName or handler is {@code null}
327      */
328     ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
329 
330     /**
331      * Inserts a {@link ChannelHandler} after an existing handler of this
332      * pipeline.
333      *
334      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
335      *                  methods
336      * @param baseName  the name of the existing handler
337      * @param name      the name of the handler to insert after
338      * @param handler   the handler to insert after
339      *
340      * @throws NoSuchElementException
341      *         if there's no such entry with the specified {@code baseName}
342      * @throws IllegalArgumentException
343      *         if there's an entry with the same name already in the pipeline
344      * @throws NullPointerException
345      *         if the specified baseName or handler is {@code null}
346      */
347     ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
348 
349     /**
350      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
351      *
352      * @param handlers  the handlers to insert first
353      *
354      */
355     ChannelPipeline addFirst(ChannelHandler... handlers);
356 
357     /**
358      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
359      *
360      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
361      *                  methods.
362      * @param handlers  the handlers to insert first
363      *
364      */
365     ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
366 
367     /**
368      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
369      *
370      * @param handlers  the handlers to insert last
371      *
372      */
373     ChannelPipeline addLast(ChannelHandler... handlers);
374 
375     /**
376      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
377      *
378      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
379      *                  methods.
380      * @param handlers  the handlers to insert last
381      *
382      */
383     ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
384 
385     /**
386      * Removes the specified {@link ChannelHandler} from this pipeline.
387      *
388      * @param  handler          the {@link ChannelHandler} to remove
389      *
390      * @throws NoSuchElementException
391      *         if there's no such handler in this pipeline
392      * @throws NullPointerException
393      *         if the specified handler is {@code null}
394      */
395     ChannelPipeline remove(ChannelHandler handler);
396 
397     /**
398      * Removes the {@link ChannelHandler} with the specified name from this pipeline.
399      *
400      * @param  name             the name under which the {@link ChannelHandler} was stored.
401      *
402      * @return the removed handler
403      *
404      * @throws NoSuchElementException
405      *         if there's no such handler with the specified name in this pipeline
406      * @throws NullPointerException
407      *         if the specified name is {@code null}
408      */
409     ChannelHandler remove(String name);
410 
411     /**
412      * Removes the {@link ChannelHandler} of the specified type from this pipeline.
413      *
414      * @param <T>           the type of the handler
415      * @param handlerType   the type of the handler
416      *
417      * @return the removed handler
418      *
419      * @throws NoSuchElementException
420      *         if there's no such handler of the specified type in this pipeline
421      * @throws NullPointerException
422      *         if the specified handler type is {@code null}
423      */
424     <T extends ChannelHandler> T remove(Class<T> handlerType);
425 
426     /**
427      * Removes the first {@link ChannelHandler} in this pipeline.
428      *
429      * @return the removed handler
430      *
431      * @throws NoSuchElementException
432      *         if this pipeline is empty
433      */
434     ChannelHandler removeFirst();
435 
436     /**
437      * Removes the last {@link ChannelHandler} in this pipeline.
438      *
439      * @return the removed handler
440      *
441      * @throws NoSuchElementException
442      *         if this pipeline is empty
443      */
444     ChannelHandler removeLast();
445 
446     /**
447      * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
448      *
449      * @param  oldHandler    the {@link ChannelHandler} to be replaced
450      * @param  newName       the name under which the replacement should be added
451      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
452      *
453      * @return itself
454 
455      * @throws NoSuchElementException
456      *         if the specified old handler does not exist in this pipeline
457      * @throws IllegalArgumentException
458      *         if a handler with the specified new name already exists in this
459      *         pipeline, except for the handler to be replaced
460      * @throws NullPointerException
461      *         if the specified old handler or new handler is
462      *         {@code null}
463      */
464     ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
465 
466     /**
467      * Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
468      *
469      * @param  oldName       the name of the {@link ChannelHandler} to be replaced
470      * @param  newName       the name under which the replacement should be added
471      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
472      *
473      * @return the removed handler
474      *
475      * @throws NoSuchElementException
476      *         if the handler with the specified old name does not exist in this pipeline
477      * @throws IllegalArgumentException
478      *         if a handler with the specified new name already exists in this
479      *         pipeline, except for the handler to be replaced
480      * @throws NullPointerException
481      *         if the specified old handler or new handler is
482      *         {@code null}
483      */
484     ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
485 
486     /**
487      * Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
488      *
489      * @param  oldHandlerType   the type of the handler to be removed
490      * @param  newName          the name under which the replacement should be added
491      * @param  newHandler       the {@link ChannelHandler} which is used as replacement
492      *
493      * @return the removed handler
494      *
495      * @throws NoSuchElementException
496      *         if the handler of the specified old handler type does not exist
497      *         in this pipeline
498      * @throws IllegalArgumentException
499      *         if a handler with the specified new name already exists in this
500      *         pipeline, except for the handler to be replaced
501      * @throws NullPointerException
502      *         if the specified old handler or new handler is
503      *         {@code null}
504      */
505     <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
506                                          ChannelHandler newHandler);
507 
508     /**
509      * Returns the first {@link ChannelHandler} in this pipeline.
510      *
511      * @return the first handler.  {@code null} if this pipeline is empty.
512      */
513     ChannelHandler first();
514 
515     /**
516      * Returns the context of the first {@link ChannelHandler} in this pipeline.
517      *
518      * @return the context of the first handler.  {@code null} if this pipeline is empty.
519      */
520     ChannelHandlerContext firstContext();
521 
522     /**
523      * Returns the last {@link ChannelHandler} in this pipeline.
524      *
525      * @return the last handler.  {@code null} if this pipeline is empty.
526      */
527     ChannelHandler last();
528 
529     /**
530      * Returns the context of the last {@link ChannelHandler} in this pipeline.
531      *
532      * @return the context of the last handler.  {@code null} if this pipeline is empty.
533      */
534     ChannelHandlerContext lastContext();
535 
536     /**
537      * Returns the {@link ChannelHandler} with the specified name in this
538      * pipeline.
539      *
540      * @return the handler with the specified name.
541      *         {@code null} if there's no such handler in this pipeline.
542      */
543     ChannelHandler get(String name);
544 
545     /**
546      * Returns the {@link ChannelHandler} of the specified type in this
547      * pipeline.
548      *
549      * @return the handler of the specified handler type.
550      *         {@code null} if there's no such handler in this pipeline.
551      */
552     <T extends ChannelHandler> T get(Class<T> handlerType);
553 
554     /**
555      * Returns the context object of the specified {@link ChannelHandler} in
556      * this pipeline.
557      *
558      * @return the context object of the specified handler.
559      *         {@code null} if there's no such handler in this pipeline.
560      */
561     ChannelHandlerContext context(ChannelHandler handler);
562 
563     /**
564      * Returns the context object of the {@link ChannelHandler} with the
565      * specified name in this pipeline.
566      *
567      * @return the context object of the handler with the specified name.
568      *         {@code null} if there's no such handler in this pipeline.
569      */
570     ChannelHandlerContext context(String name);
571 
572     /**
573      * Returns the context object of the {@link ChannelHandler} of the
574      * specified type in this pipeline.
575      *
576      * @return the context object of the handler of the specified type.
577      *         {@code null} if there's no such handler in this pipeline.
578      */
579     ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
580 
581     /**
582      * Returns the {@link Channel} that this pipeline is attached to.
583      *
584      * @return the channel. {@code null} if this pipeline is not attached yet.
585      */
586     Channel channel();
587 
588     /**
589      * Returns the {@link List} of the handler names.
590      */
591     List<String> names();
592 
593     /**
594      * Converts this pipeline into an ordered {@link Map} whose keys are
595      * handler names and whose values are handlers.
596      */
597     Map<String, ChannelHandler> toMap();
598 
599     /**
600      * A {@link Channel} was registered to its {@link EventLoop}.
601      *
602      * This will result in having the  {@link ChannelInboundHandler#channelRegistered(ChannelHandlerContext)} method
603      * called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
604      * {@link Channel}.
605      */
606     ChannelPipeline fireChannelRegistered();
607 
608     /**
609      * A {@link Channel} was unregistered from its {@link EventLoop}.
610      *
611      * This will result in having the  {@link ChannelInboundHandler#channelUnregistered(ChannelHandlerContext)} method
612      * called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
613      * {@link Channel}.
614      */
615     ChannelPipeline fireChannelUnregistered();
616 
617     /**
618      * A {@link Channel} is active now, which means it is connected.
619      *
620      * This will result in having the  {@link ChannelInboundHandler#channelActive(ChannelHandlerContext)} method
621      * called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
622      * {@link Channel}.
623      */
624     ChannelPipeline fireChannelActive();
625 
626     /**
627      * A {@link Channel} is inactive now, which means it is closed.
628      *
629      * This will result in having the  {@link ChannelInboundHandler#channelInactive(ChannelHandlerContext)} method
630      * called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
631      * {@link Channel}.
632      */
633     ChannelPipeline fireChannelInactive();
634 
635     /**
636      * A {@link Channel} received an {@link Throwable} in one of its inbound operations.
637      *
638      * This will result in having the  {@link ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)}
639      * method  called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
640      * {@link Channel}.
641      */
642     ChannelPipeline fireExceptionCaught(Throwable cause);
643 
644     /**
645      * A {@link Channel} received an user defined event.
646      *
647      * This will result in having the  {@link ChannelInboundHandler#userEventTriggered(ChannelHandlerContext, Object)}
648      * method  called of the next  {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
649      * {@link Channel}.
650      */
651     ChannelPipeline fireUserEventTriggered(Object event);
652 
653     /**
654      * A {@link Channel} received a message.
655      *
656      * This will result in having the {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)}
657      * method  called of the next {@link ChannelInboundHandler} contained in the  {@link ChannelPipeline} of the
658      * {@link Channel}.
659      */
660     ChannelPipeline fireChannelRead(Object msg);
661 
662     /**
663      * Triggers an {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext)}
664      * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}.
665      */
666     ChannelPipeline fireChannelReadComplete();
667 
668     /**
669      * Triggers an {@link ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)}
670      * event to the next {@link ChannelInboundHandler} in the {@link ChannelPipeline}.
671      */
672     ChannelPipeline fireChannelWritabilityChanged();
673 
674     /**
675      * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
676      * completes, either because the operation was successful or because of an error.
677      * <p>
678      * This will result in having the
679      * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
680      * called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
681      * {@link Channel}.
682      */
683     ChannelFuture bind(SocketAddress localAddress);
684 
685     /**
686      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
687      * completes, either because the operation was successful or because of an error.
688      * <p>
689      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
690      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
691      * will be used.
692      * <p>
693      * This will result in having the
694      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
695      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
696      * {@link Channel}.
697      */
698     ChannelFuture connect(SocketAddress remoteAddress);
699 
700     /**
701      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
702      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
703      * an error.
704      * <p>
705      * This will result in having the
706      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
707      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
708      * {@link Channel}.
709      */
710     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress);
711 
712     /**
713      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
714      * either because the operation was successful or because of an error.
715      * <p>
716      * This will result in having the
717      * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
718      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
719      * {@link Channel}.
720      */
721     ChannelFuture disconnect();
722 
723     /**
724      * Request to close the {@link Channel} and notify the {@link ChannelFuture} once the operation completes,
725      * either because the operation was successful or because of
726      * an error.
727      *
728      * After it is closed it is not possible to reuse it again.
729      * <p>
730      * This will result in having the
731      * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
732      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
733      * {@link Channel}.
734      */
735     ChannelFuture close();
736 
737     /**
738      * Request to deregister the {@link Channel} from the previous assigned {@link EventExecutor} and notify the
739      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
740      * an error.
741      * <p>
742      * This will result in having the
743      * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
744      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
745      * {@link Channel}.
746      *
747      */
748     ChannelFuture deregister();
749 
750     /**
751      * Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
752      * completes, either because the operation was successful or because of an error.
753      *
754      * The given {@link ChannelPromise} will be notified.
755      * <p>
756      * This will result in having the
757      * {@link ChannelOutboundHandler#bind(ChannelHandlerContext, SocketAddress, ChannelPromise)} method
758      * called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
759      * {@link Channel}.
760      */
761     ChannelFuture bind(SocketAddress localAddress, ChannelPromise promise);
762 
763     /**
764      * Request to connect to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
765      * completes, either because the operation was successful or because of an error.
766      *
767      * The given {@link ChannelFuture} will be notified.
768      *
769      * <p>
770      * If the connection fails because of a connection timeout, the {@link ChannelFuture} will get failed with
771      * a {@link ConnectTimeoutException}. If it fails because of connection refused a {@link ConnectException}
772      * will be used.
773      * <p>
774      * This will result in having the
775      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
776      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
777      * {@link Channel}.
778      */
779     ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise);
780 
781     /**
782      * Request to connect to the given {@link SocketAddress} while bind to the localAddress and notify the
783      * {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
784      * an error.
785      *
786      * The given {@link ChannelPromise} will be notified and also returned.
787      * <p>
788      * This will result in having the
789      * {@link ChannelOutboundHandler#connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)}
790      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
791      * {@link Channel}.
792      */
793     ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise);
794 
795     /**
796      * Request to disconnect from the remote peer and notify the {@link ChannelFuture} once the operation completes,
797      * either because the operation was successful or because of an error.
798      *
799      * The given {@link ChannelPromise} will be notified.
800      * <p>
801      * This will result in having the
802      * {@link ChannelOutboundHandler#disconnect(ChannelHandlerContext, ChannelPromise)}
803      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
804      * {@link Channel}.
805      */
806     ChannelFuture disconnect(ChannelPromise promise);
807 
808     /**
809      * Request to close the {@link Channel} bound to this {@link ChannelPipeline} and notify the {@link ChannelFuture}
810      * once the operation completes, either because the operation was successful or because of
811      * an error.
812      *
813      * After it is closed it is not possible to reuse it again.
814      * The given {@link ChannelPromise} will be notified.
815      * <p>
816      * This will result in having the
817      * {@link ChannelOutboundHandler#close(ChannelHandlerContext, ChannelPromise)}
818      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
819      * {@link Channel}.
820      */
821     ChannelFuture close(ChannelPromise promise);
822 
823     /**
824      * Request to deregister the {@link Channel} bound this {@link ChannelPipeline} from the previous assigned
825      * {@link EventExecutor} and notify the {@link ChannelFuture} once the operation completes, either because the
826      * operation was successful or because of an error.
827      *
828      * The given {@link ChannelPromise} will be notified.
829      * <p>
830      * This will result in having the
831      * {@link ChannelOutboundHandler#deregister(ChannelHandlerContext, ChannelPromise)}
832      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
833      * {@link Channel}.
834      */
835     ChannelFuture deregister(ChannelPromise promise);
836 
837     /**
838      * Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
839      * {@link ChannelInboundHandler#channelRead(ChannelHandlerContext, Object)} event if data was
840      * read, and triggers a
841      * {@link ChannelInboundHandler#channelReadComplete(ChannelHandlerContext) channelReadComplete} event so the
842      * handler can decide to continue reading.  If there's a pending read operation already, this method does nothing.
843      * <p>
844      * This will result in having the
845      * {@link ChannelOutboundHandler#read(ChannelHandlerContext)}
846      * method called of the next {@link ChannelOutboundHandler} contained in the  {@link ChannelPipeline} of the
847      * {@link Channel}.
848      */
849     ChannelPipeline read();
850 
851     /**
852      * Request to write a message via this {@link ChannelPipeline}.
853      * This method will not request to actual flush, so be sure to call {@link #flush()}
854      * once you want to request to flush all pending data to the actual transport.
855      */
856     ChannelFuture write(Object msg);
857 
858     /**
859      * Request to write a message via this {@link ChannelPipeline}.
860      * This method will not request to actual flush, so be sure to call {@link #flush()}
861      * once you want to request to flush all pending data to the actual transport.
862      */
863     ChannelFuture write(Object msg, ChannelPromise promise);
864 
865     /**
866      * Request to flush all pending messages.
867      */
868     ChannelPipeline flush();
869 
870     /**
871      * Shortcut for call {@link #write(Object, ChannelPromise)} and {@link #flush()}.
872      */
873     ChannelFuture writeAndFlush(Object msg, ChannelPromise promise);
874 
875     /**
876      * Shortcut for call {@link #write(Object)} and {@link #flush()}.
877      */
878     ChannelFuture writeAndFlush(Object msg);
879 }