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.EventExecutorGroup;
21  
22  import java.net.SocketAddress;
23  import java.nio.ByteBuffer;
24  import java.nio.channels.SocketChannel;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Map.Entry;
28  import java.util.NoSuchElementException;
29  
30  
31  /**
32   * A list of {@link ChannelHandler}s which handles or intercepts inbound events and outbound operations of a
33   * {@link Channel}.  {@link ChannelPipeline} implements an advanced form of the
34   * <a href="http://www.oracle.com/technetwork/java/interceptingfilter-142169.html">Intercepting Filter</a> pattern
35   * to give a user full control over how an event is handled and how the {@link ChannelHandler}s in a pipeline
36   * interact with each other.
37   *
38   * <h3>Creation of a pipeline</h3>
39   *
40   * Each channel has its own pipeline and it is created automatically when a new channel is created.
41   *
42   * <h3>How an event flows in a pipeline</h3>
43   *
44   * The following diagram describes how I/O events are processed by {@link ChannelHandler}s in a {@link ChannelPipeline}
45   * typically. An I/O event is handled by either a {@link ChannelInboundHandler} or a {@link ChannelOutboundHandler}
46   * and be forwarded to its closest handler by calling the event propagation methods defined in
47   * {@link ChannelHandlerContext}, such as {@link ChannelHandlerContext#fireChannelRead(Object)} and
48   * {@link ChannelHandlerContext#write(Object)}.
49   *
50   * <pre>
51   *                                                 I/O Request
52   *                                            via {@link Channel} or
53   *                                        {@link ChannelHandlerContext}
54   *                                                      |
55   *  +---------------------------------------------------+---------------+
56   *  |                           ChannelPipeline         |               |
57   *  |                                                  \|/              |
58   *  |    +---------------------+            +-----------+----------+    |
59   *  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
60   *  |    +----------+----------+            +-----------+----------+    |
61   *  |              /|\                                  |               |
62   *  |               |                                  \|/              |
63   *  |    +----------+----------+            +-----------+----------+    |
64   *  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
65   *  |    +----------+----------+            +-----------+----------+    |
66   *  |              /|\                                  .               |
67   *  |               .                                   .               |
68   *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
69   *  |        [ method call]                       [method call]         |
70   *  |               .                                   .               |
71   *  |               .                                  \|/              |
72   *  |    +----------+----------+            +-----------+----------+    |
73   *  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
74   *  |    +----------+----------+            +-----------+----------+    |
75   *  |              /|\                                  |               |
76   *  |               |                                  \|/              |
77   *  |    +----------+----------+            +-----------+----------+    |
78   *  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
79   *  |    +----------+----------+            +-----------+----------+    |
80   *  |              /|\                                  |               |
81   *  +---------------+-----------------------------------+---------------+
82   *                  |                                  \|/
83   *  +---------------+-----------------------------------+---------------+
84   *  |               |                                   |               |
85   *  |       [ Socket.read() ]                    [ Socket.write() ]     |
86   *  |                                                                   |
87   *  |  Netty Internal I/O Threads (Transport Implementation)            |
88   *  +-------------------------------------------------------------------+
89   * </pre>
90   * An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the
91   * diagram.  An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the
92   * diagram.  The inbound data is often read from a remote peer via the actual input operation such as
93   * {@link SocketChannel#read(ByteBuffer)}.  If an inbound event goes beyond the top inbound handler, it is discarded
94   * silently, or logged if it needs your attention.
95   * <p>
96   * An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the
97   * diagram.  An outbound handler usually generates or transforms the outbound traffic such as write requests.
98   * If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the
99   * {@link Channel}. The I/O thread often performs the actual output operation such as
100  * {@link SocketChannel#write(ByteBuffer)}.
101  * <p>
102  * For example, let us assume that we created the following pipeline:
103  * <pre>
104  * {@link ChannelPipeline} p = ...;
105  * p.addLast("1", new InboundHandlerA());
106  * p.addLast("2", new InboundHandlerB());
107  * p.addLast("3", new OutboundHandlerA());
108  * p.addLast("4", new OutboundHandlerB());
109  * p.addLast("5", new InboundOutboundHandlerX());
110  * </pre>
111  * In the example above, the class whose name starts with {@code Inbound} means it is an inbound handler.
112  * The class whose name starts with {@code Outbound} means it is a outbound handler.
113  * <p>
114  * In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound.
115  * When an event goes outbound, the order is 5, 4, 3, 2, 1.  On top of this principle, {@link ChannelPipeline} skips
116  * the evaluation of certain handlers to shorten the stack depth:
117  * <ul>
118  * <li>3 and 4 don't implement {@link ChannelInboundHandler}, and therefore the actual evaluation order of an inbound
119  *     event will be: 1, 2, and 5.</li>
120  * <li>1 and 2 don't implement {@link ChannelOutboundHandler}, and therefore the actual evaluation order of a
121  *     outbound event will be: 5, 4, and 3.</li>
122  * <li>If 5 implements both {@link ChannelInboundHandler} and {@link ChannelOutboundHandler}, the evaluation order of
123  *     an inbound and a outbound event could be 125 and 543 respectively.</li>
124  * </ul>
125  *
126  * <h3>Forwarding an event to the next handler</h3>
127  *
128  * As you might noticed in the diagram shows, a handler has to invoke the event propagation methods in
129  * {@link ChannelHandlerContext} to forward an event to its next handler.  Those methods include:
130  * <ul>
131  * <li>Inbound event propagation methods:
132  *     <ul>
133  *     <li>{@link ChannelHandlerContext#fireChannelRegistered()}</li>
134  *     <li>{@link ChannelHandlerContext#fireChannelActive()}</li>
135  *     <li>{@link ChannelHandlerContext#fireChannelRead(Object)}</li>
136  *     <li>{@link ChannelHandlerContext#fireChannelReadComplete()}</li>
137  *     <li>{@link ChannelHandlerContext#fireExceptionCaught(Throwable)}</li>
138  *     <li>{@link ChannelHandlerContext#fireUserEventTriggered(Object)}</li>
139  *     <li>{@link ChannelHandlerContext#fireChannelWritabilityChanged()}</li>
140  *     <li>{@link ChannelHandlerContext#fireChannelInactive()}</li>
141  *     <li>{@link ChannelHandlerContext#fireChannelUnregistered()}</li>
142  *     </ul>
143  * </li>
144  * <li>Outbound event propagation methods:
145  *     <ul>
146  *     <li>{@link ChannelHandlerContext#bind(SocketAddress, ChannelPromise)}</li>
147  *     <li>{@link ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)}</li>
148  *     <li>{@link ChannelHandlerContext#write(Object, ChannelPromise)}</li>
149  *     <li>{@link ChannelHandlerContext#flush()}</li>
150  *     <li>{@link ChannelHandlerContext#read()}</li>
151  *     <li>{@link ChannelHandlerContext#disconnect(ChannelPromise)}</li>
152  *     <li>{@link ChannelHandlerContext#close(ChannelPromise)}</li>
153  *     <li>{@link ChannelHandlerContext#deregister(ChannelPromise)}</li>
154  *     </ul>
155  * </li>
156  * </ul>
157  *
158  * and the following example shows how the event propagation is usually done:
159  *
160  * <pre>
161  * public class MyInboundHandler extends {@link ChannelInboundHandlerAdapter} {
162  *     {@code @Override}
163  *     public void channelActive({@link ChannelHandlerContext} ctx) {
164  *         System.out.println("Connected!");
165  *         ctx.fireChannelActive();
166  *     }
167  * }
168  *
169  * public class MyOutboundHandler extends {@link ChannelOutboundHandlerAdapter} {
170  *     {@code @Override}
171  *     public void close({@link ChannelHandlerContext} ctx, {@link ChannelPromise} promise) {
172  *         System.out.println("Closing ..");
173  *         ctx.close(promise);
174  *     }
175  * }
176  * </pre>
177  *
178  * <h3>Building a pipeline</h3>
179  * <p>
180  * A user is supposed to have one or more {@link ChannelHandler}s in a pipeline to receive I/O events (e.g. read) and
181  * to request I/O operations (e.g. write and close).  For example, a typical server will have the following handlers
182  * in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the
183  * protocol and business logic:
184  *
185  * <ol>
186  * <li>Protocol Decoder - translates binary data (e.g. {@link ByteBuf}) into a Java object.</li>
187  * <li>Protocol Encoder - translates a Java object into binary data.</li>
188  * <li>Business Logic Handler - performs the actual business logic (e.g. database access).</li>
189  * </ol>
190  *
191  * and it could be represented as shown in the following example:
192  *
193  * <pre>
194  * static final {@link EventExecutorGroup} group = new {@link DefaultEventExecutorGroup}(16);
195  * ...
196  *
197  * {@link ChannelPipeline} pipeline = ch.pipeline();
198  *
199  * pipeline.addLast("decoder", new MyProtocolDecoder());
200  * pipeline.addLast("encoder", new MyProtocolEncoder());
201  *
202  * // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
203  * // in a different thread than an I/O thread so that the I/O thread is not blocked by
204  * // a time-consuming task.
205  * // If your business logic is fully asynchronous or finished very quickly, you don't
206  * // need to specify a group.
207  * pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
208  * </pre>
209  *
210  * <h3>Thread safety</h3>
211  * <p>
212  * A {@link ChannelHandler} can be added or removed at any time because a {@link ChannelPipeline} is thread safe.
213  * For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
214  * after the exchange.
215  */
216 public interface ChannelPipeline
217         extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Entry<String, ChannelHandler>> {
218 
219     /**
220      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
221      *
222      * @param name     the name of the handler to insert first
223      * @param handler  the handler to insert first
224      *
225      * @throws IllegalArgumentException
226      *         if there's an entry with the same name already in the pipeline
227      * @throws NullPointerException
228      *         if the specified handler is {@code null}
229      */
230     ChannelPipeline addFirst(String name, ChannelHandler handler);
231 
232     /**
233      * Inserts a {@link ChannelHandler} at the first position of this pipeline.
234      *
235      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
236      *                 methods
237      * @param name     the name of the handler to insert first
238      * @param handler  the handler to insert first
239      *
240      * @throws IllegalArgumentException
241      *         if there's an entry with the same name already in the pipeline
242      * @throws NullPointerException
243      *         if the specified handler is {@code null}
244      */
245     ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler);
246 
247     /**
248      * Appends a {@link ChannelHandler} at the last position of this pipeline.
249      *
250      * @param name     the name of the handler to append
251      * @param handler  the handler to append
252      *
253      * @throws IllegalArgumentException
254      *         if there's an entry with the same name already in the pipeline
255      * @throws NullPointerException
256      *         if the specified handler is {@code null}
257      */
258     ChannelPipeline addLast(String name, ChannelHandler handler);
259 
260     /**
261      * Appends a {@link ChannelHandler} at the last position of this pipeline.
262      *
263      * @param group    the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
264      *                 methods
265      * @param name     the name of the handler to append
266      * @param handler  the handler to append
267      *
268      * @throws IllegalArgumentException
269      *         if there's an entry with the same name already in the pipeline
270      * @throws NullPointerException
271      *         if the specified handler is {@code null}
272      */
273     ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler);
274 
275     /**
276      * Inserts a {@link ChannelHandler} before an existing handler of this
277      * pipeline.
278      *
279      * @param baseName  the name of the existing handler
280      * @param name      the name of the handler to insert before
281      * @param handler   the handler to insert before
282      *
283      * @throws NoSuchElementException
284      *         if there's no such entry with the specified {@code baseName}
285      * @throws IllegalArgumentException
286      *         if there's an entry with the same name already in the pipeline
287      * @throws NullPointerException
288      *         if the specified baseName or handler is {@code null}
289      */
290     ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler);
291 
292     /**
293      * Inserts a {@link ChannelHandler} before an existing handler of this
294      * pipeline.
295      *
296      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
297      *                  methods
298      * @param baseName  the name of the existing handler
299      * @param name      the name of the handler to insert before
300      * @param handler   the handler to insert before
301      *
302      * @throws NoSuchElementException
303      *         if there's no such entry with the specified {@code baseName}
304      * @throws IllegalArgumentException
305      *         if there's an entry with the same name already in the pipeline
306      * @throws NullPointerException
307      *         if the specified baseName or handler is {@code null}
308      */
309     ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
310 
311     /**
312      * Inserts a {@link ChannelHandler} after an existing handler of this
313      * pipeline.
314      *
315      * @param baseName  the name of the existing handler
316      * @param name      the name of the handler to insert after
317      * @param handler   the handler to insert after
318      *
319      * @throws NoSuchElementException
320      *         if there's no such entry with the specified {@code baseName}
321      * @throws IllegalArgumentException
322      *         if there's an entry with the same name already in the pipeline
323      * @throws NullPointerException
324      *         if the specified baseName or handler is {@code null}
325      */
326     ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler);
327 
328     /**
329      * Inserts a {@link ChannelHandler} after an existing handler of this
330      * pipeline.
331      *
332      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}
333      *                  methods
334      * @param baseName  the name of the existing handler
335      * @param name      the name of the handler to insert after
336      * @param handler   the handler to insert after
337      *
338      * @throws NoSuchElementException
339      *         if there's no such entry with the specified {@code baseName}
340      * @throws IllegalArgumentException
341      *         if there's an entry with the same name already in the pipeline
342      * @throws NullPointerException
343      *         if the specified baseName or handler is {@code null}
344      */
345     ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler);
346 
347     /**
348      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
349      *
350      * @param handlers  the handlers to insert first
351      *
352      */
353     ChannelPipeline addFirst(ChannelHandler... handlers);
354 
355     /**
356      * Inserts {@link ChannelHandler}s at the first position of this pipeline.
357      *
358      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
359      *                  methods.
360      * @param handlers  the handlers to insert first
361      *
362      */
363     ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers);
364 
365     /**
366      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
367      *
368      * @param handlers  the handlers to insert last
369      *
370      */
371     ChannelPipeline addLast(ChannelHandler... handlers);
372 
373     /**
374      * Inserts {@link ChannelHandler}s at the last position of this pipeline.
375      *
376      * @param group     the {@link EventExecutorGroup} which will be used to execute the {@link ChannelHandler}s
377      *                  methods.
378      * @param handlers  the handlers to insert last
379      *
380      */
381     ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers);
382 
383     /**
384      * Removes the specified {@link ChannelHandler} from this pipeline.
385      *
386      * @param  handler          the {@link ChannelHandler} to remove
387      *
388      * @throws NoSuchElementException
389      *         if there's no such handler in this pipeline
390      * @throws NullPointerException
391      *         if the specified handler is {@code null}
392      */
393     ChannelPipeline remove(ChannelHandler handler);
394 
395     /**
396      * Removes the {@link ChannelHandler} with the specified name from this pipeline.
397      *
398      * @param  name             the name under which the {@link ChannelHandler} was stored.
399      *
400      * @return the removed handler
401      *
402      * @throws NoSuchElementException
403      *         if there's no such handler with the specified name in this pipeline
404      * @throws NullPointerException
405      *         if the specified name is {@code null}
406      */
407     ChannelHandler remove(String name);
408 
409     /**
410      * Removes the {@link ChannelHandler} of the specified type from this pipeline.
411      *
412      * @param <T>           the type of the handler
413      * @param handlerType   the type of the handler
414      *
415      * @return the removed handler
416      *
417      * @throws NoSuchElementException
418      *         if there's no such handler of the specified type in this pipeline
419      * @throws NullPointerException
420      *         if the specified handler type is {@code null}
421      */
422     <T extends ChannelHandler> T remove(Class<T> handlerType);
423 
424     /**
425      * Removes the first {@link ChannelHandler} in this pipeline.
426      *
427      * @return the removed handler
428      *
429      * @throws NoSuchElementException
430      *         if this pipeline is empty
431      */
432     ChannelHandler removeFirst();
433 
434     /**
435      * Removes the last {@link ChannelHandler} in this pipeline.
436      *
437      * @return the removed handler
438      *
439      * @throws NoSuchElementException
440      *         if this pipeline is empty
441      */
442     ChannelHandler removeLast();
443 
444     /**
445      * Replaces the specified {@link ChannelHandler} with a new handler in this pipeline.
446      *
447      * @param  oldHandler    the {@link ChannelHandler} to be replaced
448      * @param  newName       the name under which the replacement should be added
449      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
450      *
451      * @return itself
452 
453      * @throws NoSuchElementException
454      *         if the specified old handler does not exist in this pipeline
455      * @throws IllegalArgumentException
456      *         if a handler with the specified new name already exists in this
457      *         pipeline, except for the handler to be replaced
458      * @throws NullPointerException
459      *         if the specified old handler or new handler is
460      *         {@code null}
461      */
462     ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler);
463 
464     /**
465      * Replaces the {@link ChannelHandler} of the specified name with a new handler in this pipeline.
466      *
467      * @param  oldName       the name of the {@link ChannelHandler} to be replaced
468      * @param  newName       the name under which the replacement should be added
469      * @param  newHandler    the {@link ChannelHandler} which is used as replacement
470      *
471      * @return the removed handler
472      *
473      * @throws NoSuchElementException
474      *         if the handler with the specified old name does not exist in this pipeline
475      * @throws IllegalArgumentException
476      *         if a handler with the specified new name already exists in this
477      *         pipeline, except for the handler to be replaced
478      * @throws NullPointerException
479      *         if the specified old handler or new handler is
480      *         {@code null}
481      */
482     ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler);
483 
484     /**
485      * Replaces the {@link ChannelHandler} of the specified type with a new handler in this pipeline.
486      *
487      * @param  oldHandlerType   the type of the handler to be removed
488      * @param  newName          the name under which the replacement should be added
489      * @param  newHandler       the {@link ChannelHandler} which is used as replacement
490      *
491      * @return the removed handler
492      *
493      * @throws NoSuchElementException
494      *         if the handler of the specified old handler type does not exist
495      *         in this pipeline
496      * @throws IllegalArgumentException
497      *         if a handler with the specified new name already exists in this
498      *         pipeline, except for the handler to be replaced
499      * @throws NullPointerException
500      *         if the specified old handler or new handler is
501      *         {@code null}
502      */
503     <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName,
504                                          ChannelHandler newHandler);
505 
506     /**
507      * Returns the first {@link ChannelHandler} in this pipeline.
508      *
509      * @return the first handler.  {@code null} if this pipeline is empty.
510      */
511     ChannelHandler first();
512 
513     /**
514      * Returns the context of the first {@link ChannelHandler} in this pipeline.
515      *
516      * @return the context of the first handler.  {@code null} if this pipeline is empty.
517      */
518     ChannelHandlerContext firstContext();
519 
520     /**
521      * Returns the last {@link ChannelHandler} in this pipeline.
522      *
523      * @return the last handler.  {@code null} if this pipeline is empty.
524      */
525     ChannelHandler last();
526 
527     /**
528      * Returns the context of the last {@link ChannelHandler} in this pipeline.
529      *
530      * @return the context of the last handler.  {@code null} if this pipeline is empty.
531      */
532     ChannelHandlerContext lastContext();
533 
534     /**
535      * Returns the {@link ChannelHandler} with the specified name in this
536      * pipeline.
537      *
538      * @return the handler with the specified name.
539      *         {@code null} if there's no such handler in this pipeline.
540      */
541     ChannelHandler get(String name);
542 
543     /**
544      * Returns the {@link ChannelHandler} of the specified type in this
545      * pipeline.
546      *
547      * @return the handler of the specified handler type.
548      *         {@code null} if there's no such handler in this pipeline.
549      */
550     <T extends ChannelHandler> T get(Class<T> handlerType);
551 
552     /**
553      * Returns the context object of the specified {@link ChannelHandler} in
554      * this pipeline.
555      *
556      * @return the context object of the specified handler.
557      *         {@code null} if there's no such handler in this pipeline.
558      */
559     ChannelHandlerContext context(ChannelHandler handler);
560 
561     /**
562      * Returns the context object of the {@link ChannelHandler} with the
563      * specified name in this pipeline.
564      *
565      * @return the context object of the handler with the specified name.
566      *         {@code null} if there's no such handler in this pipeline.
567      */
568     ChannelHandlerContext context(String name);
569 
570     /**
571      * Returns the context object of the {@link ChannelHandler} of the
572      * specified type in this pipeline.
573      *
574      * @return the context object of the handler of the specified type.
575      *         {@code null} if there's no such handler in this pipeline.
576      */
577     ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType);
578 
579     /**
580      * Returns the {@link Channel} that this pipeline is attached to.
581      *
582      * @return the channel. {@code null} if this pipeline is not attached yet.
583      */
584     Channel channel();
585 
586     /**
587      * Returns the {@link List} of the handler names.
588      */
589     List<String> names();
590 
591     /**
592      * Converts this pipeline into an ordered {@link Map} whose keys are
593      * handler names and whose values are handlers.
594      */
595     Map<String, ChannelHandler> toMap();
596 
597     @Override
598     ChannelPipeline fireChannelRegistered();
599 
600      @Override
601     ChannelPipeline fireChannelUnregistered();
602 
603     @Override
604     ChannelPipeline fireChannelActive();
605 
606     @Override
607     ChannelPipeline fireChannelInactive();
608 
609     @Override
610     ChannelPipeline fireExceptionCaught(Throwable cause);
611 
612     @Override
613     ChannelPipeline fireUserEventTriggered(Object event);
614 
615     @Override
616     ChannelPipeline fireChannelRead(Object msg);
617 
618     @Override
619     ChannelPipeline fireChannelReadComplete();
620 
621     @Override
622     ChannelPipeline fireChannelWritabilityChanged();
623 
624     @Override
625     ChannelPipeline flush();
626 }