ChannelHandlers which handles or intercepts inbound events and outbound operations of a
Channel. ChannelPipeline implements an advanced form of the
Intercepting Filter pattern
to give a user full control over how an event is handled and how the ChannelHandlers in a pipeline
interact with each other.
ChannelHandlers in a ChannelPipeline
typically. An I/O event is handled by either a ChannelInboundHandler or a ChannelOutboundHandler
and be forwarded to its closest handler by calling the event propagation methods defined in
ChannelHandlerContext, such as ChannelHandlerContext#fireChannelRead(Object) and
ChannelHandlerContext#write(Object).
I/O Request
via Channel or
ChannelHandlerContext
|
+---------------------------------------------------+---------------+
| ChannelPipeline | |
| \|/ |
| +---------------------+ +-----------+----------+ |
| | Inbound Handler N | | Outbound Handler 1 | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler N-1 | | Outbound Handler 2 | |
| +----------+----------+ +-----------+----------+ |
| /|\ . |
| . . |
| ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
| [ method call] [method call] |
| . . |
| . \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler 2 | | Outbound Handler M-1 | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
| | \|/ |
| +----------+----------+ +-----------+----------+ |
| | Inbound Handler 1 | | Outbound Handler M | |
| +----------+----------+ +-----------+----------+ |
| /|\ | |
+---------------+-----------------------------------+---------------+
| \|/
+---------------+-----------------------------------+---------------+
| | | |
| [ Socket.read() ] [ Socket.write() ] |
| |
| Netty Internal I/O Threads (Transport Implementation) |
+-------------------------------------------------------------------+
An inbound event is handled by the inbound handlers in the bottom-up direction as shown on the left side of the
diagram. An inbound handler usually handles the inbound data generated by the I/O thread on the bottom of the
diagram. The inbound data is often read from a remote peer via the actual input operation such as
SocketChannel#read(ByteBuffer). If an inbound event goes beyond the top inbound handler, it is discarded
silently, or logged if it needs your attention.
An outbound event is handled by the outbound handler in the top-down direction as shown on the right side of the
diagram. An outbound handler usually generates or transforms the outbound traffic such as write requests.
If an outbound event goes beyond the bottom outbound handler, it is handled by an I/O thread associated with the
Channel. The I/O thread often performs the actual output operation such as
SocketChannel#write(ByteBuffer).
For example, let us assume that we created the following pipeline:
ChannelPipeline p = ...;
p.addLast("1", new InboundHandlerA());
p.addLast("2", new InboundHandlerB());
p.addLast("3", new OutboundHandlerA());
p.addLast("4", new OutboundHandlerB());
p.addLast("5", new InboundOutboundHandlerX());
In the example above, the class whose name starts with Inbound means it is an inbound handler.
The class whose name starts with Outbound means it is a outbound handler.
In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes inbound.
When an event goes outbound, the order is 5, 4, 3, 2, 1. On top of this principle, ChannelPipeline skips
the evaluation of certain handlers to shorten the stack depth:
ChannelInboundHandler, and therefore the actual evaluation order of an inbound
event will be: 1, 2, and 5.ChannelOutboundHandler, and therefore the actual evaluation order of a
outbound event will be: 5, 4, and 3.ChannelInboundHandler and ChannelOutboundHandler, the evaluation order of
an inbound and a outbound event could be 125 and 543 respectively.ChannelHandlerContext to forward an event to its next handler. Those methods include:
ChannelHandlerContext#fireChannelRegistered()ChannelHandlerContext#fireChannelActive()ChannelHandlerContext#fireChannelRead(Object)ChannelHandlerContext#fireChannelReadComplete()ChannelHandlerContext#fireExceptionCaught(Throwable)ChannelHandlerContext#fireUserEventTriggered(Object)ChannelHandlerContext#fireChannelWritabilityChanged()ChannelHandlerContext#fireChannelInactive()ChannelHandlerContext#fireChannelUnregistered()ChannelHandlerContext#bind(SocketAddress, ChannelPromise)ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise)ChannelHandlerContext#write(Object, ChannelPromise)ChannelHandlerContext#flush()ChannelHandlerContext#read()ChannelHandlerContext#disconnect(ChannelPromise)ChannelHandlerContext#close(ChannelPromise)ChannelHandlerContext#deregister(ChannelPromise)public class MyInboundHandler extendsChannelInboundHandlerAdapter{@Overridepublic void channelActive(ChannelHandlerContextctx) { System.out.println("Connected!"); ctx.fireChannelActive(); } } public class MyOutboundHandler extendsChannelOutboundHandlerAdapter{@Overridepublic void close(ChannelHandlerContextctx,ChannelPromisepromise) { System.out.println("Closing .."); ctx.close(promise); } }
A user is supposed to have one or more ChannelHandlers in a pipeline to receive I/O events (e.g. read) and
to request I/O operations (e.g. write and close). For example, a typical server will have the following handlers
in each channel's pipeline, but your mileage may vary depending on the complexity and characteristics of the
protocol and business logic:
ByteBuf) into a Java object.static finalBe aware that while usingEventExecutorGroupgroup = newDefaultEventExecutorGroup(16); ...ChannelPipelinepipeline = ch.pipeline(); pipeline.addLast("decoder", new MyProtocolDecoder()); pipeline.addLast("encoder", new MyProtocolEncoder()); // Tell the pipeline to run MyBusinessLogicHandler's event handler methods // in a different thread than an I/O thread so that the I/O thread is not blocked by // a time-consuming task. // If your business logic is fully asynchronous or finished very quickly, you don't // need to specify a group. pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
DefaultEventLoopGroup will offload the operation from the EventLoop it will
still process tasks in a serial fashion per ChannelHandlerContext and so guarantee ordering. Due the ordering
it may still become a bottle-neck. If ordering is not a requirement for your use-case you may want to consider using
UnorderedThreadPoolEventExecutor to maximize the parallelism of the task execution.
A ChannelHandler can be added or removed at any time because a ChannelPipeline is thread safe.
For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it
after the exchange.
| Modifier and Type | Method and Description |
|---|---|
| public ChannelPipeline | addAfter(String
the name of the existing handler baseName, String the name of the handler to insert after name, ChannelHandler the handler to insert after handler)Inserts a |
| public ChannelPipeline | addAfter(EventExecutorGroup
the group, String EventExecutorGroup which will be used to execute the ChannelHandler
methodsthe name of the existing handler baseName, String the name of the handler to insert after name, ChannelHandler the handler to insert after handler)Inserts a |
| public ChannelPipeline | addBefore(String
the name of the existing handler baseName, String the name of the handler to insert before name, ChannelHandler the handler to insert before handler)Inserts a |
| public ChannelPipeline | addBefore(EventExecutorGroup
the group, String EventExecutorGroup which will be used to execute the ChannelHandler
methodsthe name of the existing handler baseName, String the name of the handler to insert before name, ChannelHandler the handler to insert before handler)Inserts a |
| public ChannelPipeline | addFirst(String
the name of the handler to insert first name, ChannelHandler the handler to insert first handler)Inserts a |
| public ChannelPipeline | addFirst(EventExecutorGroup
the group, String EventExecutorGroup which will be used to execute the ChannelHandler
methodsthe name of the handler to insert first name, ChannelHandler the handler to insert first handler)Inserts a |
| public ChannelPipeline | addFirst(ChannelHandler...
the handlers to insert first handlers)Inserts |
| public ChannelPipeline | addFirst(EventExecutorGroup
the group, ChannelHandler... EventExecutorGroup which will be used to execute the ChannelHandlers
methods.the handlers to insert first handlers)Inserts |
| public ChannelPipeline | addLast(String
the name of the handler to append name, ChannelHandler the handler to append handler)Appends a |
| public ChannelPipeline | addLast(EventExecutorGroup
the group, String EventExecutorGroup which will be used to execute the ChannelHandler
methodsthe name of the handler to append name, ChannelHandler the handler to append handler)Appends a |
| public ChannelPipeline | addLast(ChannelHandler...
the handlers to insert last handlers)Inserts |
| public ChannelPipeline | addLast(EventExecutorGroup
the group, ChannelHandler... EventExecutorGroup which will be used to execute the ChannelHandlers
methods.the handlers to insert last handlers)Inserts |
| public Channel | |
| public ChannelHandlerContext | Returns: the context object of the specified handler.null if there's no such handler in this pipeline.Returns the context object of the specified |
| public ChannelHandlerContext | Returns: the context object of the handler with the specified name.null if there's no such handler in this pipeline.Returns the context object of the |
| public ChannelHandlerContext | Returns: the context object of the handler of the specified type.null if there's no such handler in this pipeline.Returns the context object of the |
| public ChannelPipeline | fireChannelActive()
Redeclares io. Channel is active now, which means it is connected.
|
| public ChannelPipeline | fireChannelInactive()
Redeclares io. Channel is inactive now, which means it is closed.
|
| public ChannelPipeline | fireChannelRead(Object msg)
Redeclares io. Channel received a message.
|
| public ChannelPipeline | fireChannelReadComplete()
Redeclares io. ChannelInboundHandler#channelReadComplete(ChannelHandlerContext)
event to the next ChannelInboundHandler in the ChannelPipeline.
|
| public ChannelPipeline | fireChannelRegistered()
Redeclares io. Channel was registered to its EventLoop.
|
| public ChannelPipeline | fireChannelUnregistered()
Redeclares io. Channel was unregistered from its EventLoop.
|
| public ChannelPipeline | fireChannelWritabilityChanged()
Redeclares io. ChannelInboundHandler#channelWritabilityChanged(ChannelHandlerContext)
event to the next ChannelInboundHandler in the ChannelPipeline.
|
| public ChannelPipeline | fireExceptionCaught(Throwable cause)
Redeclares io. Channel received an Throwable in one of its inbound operations.
|
| public ChannelPipeline | fireUserEventTriggered(Object event)
Redeclares io. Channel received an user defined event.
|
| public ChannelHandler | Returns: the first handler.null if this pipeline is empty.Returns the first |
| public ChannelHandlerContext | Returns: the context of the first handler.null if this pipeline is empty.Returns the context of the first |
| public ChannelPipeline | flush()
Redeclares io. |
| public ChannelHandler | Returns: the handler with the specified name.null if there's no such handler in this pipeline.Returns the |
| public <T extends ChannelHandler> T | Returns: the handler of the specified handler type.null if there's no such handler in this pipeline.Returns the |
| public ChannelHandler | Returns: the last handler.null if this pipeline is empty.Returns the last |
| public ChannelHandlerContext | Returns: the context of the last handler.null if this pipeline is empty.Returns the context of the last |
| public List | |
| public ChannelPipeline | remove(ChannelHandler
the handler)ChannelHandler to removeRemoves the specified |
| public ChannelHandler | Returns: the removed handlerthe name under which the name)ChannelHandler was stored.Removes the |
| public < the type of the handler T extends ChannelHandler> T | Returns: the removed handlerthe type of the handler handlerType)Removes the |
| public ChannelHandler | |
| public ChannelHandler | |
| public ChannelPipeline | Returns: itselfthe oldHandler, String ChannelHandler to be replacedthe name under which the replacement should be added newName, ChannelHandler the newHandler)ChannelHandler which is used as replacementReplaces the specified |
| public ChannelHandler | Returns: the removed handlerthe name of the oldName, String ChannelHandler to be replacedthe name under which the replacement should be added newName, ChannelHandler the newHandler)ChannelHandler which is used as replacementReplaces the |
| public <T extends ChannelHandler> T | Returns: the removed handlerthe type of the handler to be removed oldHandlerType, String the name under which the replacement should be added newName, ChannelHandler the newHandler)ChannelHandler which is used as replacementReplaces the |
| public Map |
| addAfter | back to summary |
|---|---|
| public ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler) Inserts a
| |
| addAfter | back to summary |
|---|---|
| public ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) Inserts a
| |
| addBefore | back to summary |
|---|---|
| public ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) Inserts a
| |
| addBefore | back to summary |
|---|---|
| public ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler) Inserts a
| |
| addFirst | back to summary |
|---|---|
| public ChannelPipeline addFirst(String name, ChannelHandler handler) Inserts a
| |
| addFirst | back to summary |
|---|---|
| public ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler) Inserts a
| |
| addFirst | back to summary |
|---|---|
| public ChannelPipeline addFirst(ChannelHandler... handlers) Inserts
| |
| addFirst | back to summary |
|---|---|
| public ChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers) Inserts
| |
| addLast | back to summary |
|---|---|
| public ChannelPipeline addLast(String name, ChannelHandler handler) Appends a
| |
| addLast | back to summary |
|---|---|
| public ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler) Appends a
| |
| addLast | back to summary |
|---|---|
| public ChannelPipeline addLast(ChannelHandler... handlers) Inserts
| |
| addLast | back to summary |
|---|---|
| public ChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers) Inserts
| |
| channel | back to summary |
|---|---|
| public Channel channel() Returns the
| |
| context | back to summary |
|---|---|
| public ChannelHandlerContext context(ChannelHandler handler) Returns the context object of the specified
| |
| context | back to summary |
|---|---|
| public ChannelHandlerContext context(String name) Returns the context object of the
| |
| context | back to summary |
|---|---|
| public ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType) Returns the context object of the
| |
| fireChannelActive | back to summary |
|---|---|
| public ChannelPipeline fireChannelActive() Redeclares io. Doc from io. A
| |
| fireChannelInactive | back to summary |
|---|---|
| public ChannelPipeline fireChannelInactive() Redeclares io. Doc from io. A
| |
| fireChannelRead | back to summary |
|---|---|
| public ChannelPipeline fireChannelRead(Object msg) Redeclares io. Doc from io. A
| |
| fireChannelReadComplete | back to summary |
|---|---|
| public ChannelPipeline fireChannelReadComplete() Redeclares io. Doc from io. Triggers an
| |
| fireChannelRegistered | back to summary |
|---|---|
| public ChannelPipeline fireChannelRegistered() Redeclares io. Doc from io. A
| |
| fireChannelUnregistered | back to summary |
|---|---|
| public ChannelPipeline fireChannelUnregistered() Redeclares io. Doc from io. A
| |
| fireChannelWritabilityChanged | back to summary |
|---|---|
| public ChannelPipeline fireChannelWritabilityChanged() Redeclares io. Doc from io. Triggers an
| |
| fireExceptionCaught | back to summary |
|---|---|
| public ChannelPipeline fireExceptionCaught(Throwable cause) Redeclares io. Doc from io. A
| |
| fireUserEventTriggered | back to summary |
|---|---|
| public ChannelPipeline fireUserEventTriggered(Object event) Redeclares io. Doc from io. A
| |
| first | back to summary |
|---|---|
| public ChannelHandler first() Returns the first
| |
| firstContext | back to summary |
|---|---|
| public ChannelHandlerContext firstContext() Returns the context of the first
| |
| flush | back to summary |
|---|---|
| public ChannelPipeline flush() Redeclares io. Doc from io. Request to flush all pending messages via this ChannelOutboundInvoker.
| |
| get | back to summary |
|---|---|
| public ChannelHandler get(String name) Returns the
| |
| get | back to summary |
|---|---|
| public <T extends ChannelHandler> T get(Class<T> handlerType) Returns the
| |
| last | back to summary |
|---|---|
| public ChannelHandler last() Returns the last
| |
| lastContext | back to summary |
|---|---|
| public ChannelHandlerContext lastContext() Returns the context of the last
| |
| names | back to summary |
|---|---|
| public List Returns the | |
| remove | back to summary |
|---|---|
| public ChannelPipeline remove(ChannelHandler handler) Removes the specified
| |
| remove | back to summary |
|---|---|
| public ChannelHandler remove(String name) Removes the
| |
| remove | back to summary |
|---|---|
| public <T extends ChannelHandler> T remove(Class<T> handlerType) Removes the
| |
| removeFirst | back to summary |
|---|---|
| public ChannelHandler removeFirst() Removes the first
| |
| removeLast | back to summary |
|---|---|
| public ChannelHandler removeLast() Removes the last
| |
| replace | back to summary |
|---|---|
| public ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler) Replaces the specified
| |
| replace | back to summary |
|---|---|
| public ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler) Replaces the
| |
| replace | back to summary |
|---|---|
| public <T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler) Replaces the
| |
| toMap | back to summary |
|---|---|
| public Map Converts this pipeline into an ordered | |