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 }