public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Map.Entry<String,ChannelHandler>>
ChannelHandler
s 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 ChannelHandler
s in a pipeline
interact with each other.
ChannelHandler
s 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
ChannelOutboundInvoker.write(Object)
.
I/O Request viaAn 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 asChannel
orChannelHandlerContext
| +---------------------------------------------------+---------------+ | 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) | +-------------------------------------------------------------------+
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()
ChannelOutboundInvoker.bind(SocketAddress, ChannelPromise)
ChannelOutboundInvoker.connect(SocketAddress, SocketAddress, ChannelPromise)
ChannelOutboundInvoker.write(Object, ChannelPromise)
ChannelHandlerContext.flush()
ChannelHandlerContext.read()
ChannelOutboundInvoker.disconnect(ChannelPromise)
ChannelOutboundInvoker.close(ChannelPromise)
ChannelOutboundInvoker.deregister(ChannelPromise)
public class MyInboundHandler extendsChannelInboundHandlerAdapter
{@Override
public void channelActive(ChannelHandlerContext
ctx) { System.out.println("Connected!"); ctx.fireChannelActive(); } } public class MyOutboundHandler extendsChannelOutboundHandlerAdapter
{@Override
public void close(ChannelHandlerContext
ctx,ChannelPromise
promise) { System.out.println("Closing .."); ctx.close(promise); } }
A user is supposed to have one or more ChannelHandler
s 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 usingEventExecutorGroup
group = newDefaultEventExecutorGroup
(16); ...ChannelPipeline
pipeline = 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 |
---|---|
ChannelPipeline |
addAfter(EventExecutorGroup group,
String baseName,
String name,
ChannelHandler handler)
Inserts a
ChannelHandler after an existing handler of this
pipeline. |
ChannelPipeline |
addAfter(String baseName,
String name,
ChannelHandler handler)
Inserts a
ChannelHandler after an existing handler of this
pipeline. |
ChannelPipeline |
addBefore(EventExecutorGroup group,
String baseName,
String name,
ChannelHandler handler)
Inserts a
ChannelHandler before an existing handler of this
pipeline. |
ChannelPipeline |
addBefore(String baseName,
String name,
ChannelHandler handler)
Inserts a
ChannelHandler before an existing handler of this
pipeline. |
ChannelPipeline |
addFirst(ChannelHandler... handlers)
Inserts
ChannelHandler s at the first position of this pipeline. |
ChannelPipeline |
addFirst(EventExecutorGroup group,
ChannelHandler... handlers)
Inserts
ChannelHandler s at the first position of this pipeline. |
ChannelPipeline |
addFirst(EventExecutorGroup group,
String name,
ChannelHandler handler)
Inserts a
ChannelHandler at the first position of this pipeline. |
ChannelPipeline |
addFirst(String name,
ChannelHandler handler)
Inserts a
ChannelHandler at the first position of this pipeline. |
ChannelPipeline |
addLast(ChannelHandler... handlers)
Inserts
ChannelHandler s at the last position of this pipeline. |
ChannelPipeline |
addLast(EventExecutorGroup group,
ChannelHandler... handlers)
Inserts
ChannelHandler s at the last position of this pipeline. |
ChannelPipeline |
addLast(EventExecutorGroup group,
String name,
ChannelHandler handler)
Appends a
ChannelHandler at the last position of this pipeline. |
ChannelPipeline |
addLast(String name,
ChannelHandler handler)
Appends a
ChannelHandler at the last position of this pipeline. |
Channel |
channel()
Returns the
Channel that this pipeline is attached to. |
ChannelHandlerContext |
context(ChannelHandler handler)
Returns the context object of the specified
ChannelHandler in
this pipeline. |
ChannelHandlerContext |
context(Class<? extends ChannelHandler> handlerType)
Returns the context object of the
ChannelHandler of the
specified type in this pipeline. |
ChannelHandlerContext |
context(String name)
Returns the context object of the
ChannelHandler with the
specified name in this pipeline. |
ChannelPipeline |
fireChannelActive()
A
Channel is active now, which means it is connected. |
ChannelPipeline |
fireChannelInactive()
A
Channel is inactive now, which means it is closed. |
ChannelPipeline |
fireChannelRead(Object msg)
A
Channel received a message. |
ChannelPipeline |
fireChannelReadComplete()
Triggers an
ChannelInboundHandler.channelReadComplete(ChannelHandlerContext)
event to the next ChannelInboundHandler in the ChannelPipeline . |
ChannelPipeline |
fireChannelRegistered()
|
ChannelPipeline |
fireChannelUnregistered()
|
ChannelPipeline |
fireChannelWritabilityChanged()
Triggers an
ChannelInboundHandler.channelWritabilityChanged(ChannelHandlerContext)
event to the next ChannelInboundHandler in the ChannelPipeline . |
ChannelPipeline |
fireExceptionCaught(Throwable cause)
|
ChannelPipeline |
fireUserEventTriggered(Object event)
A
Channel received an user defined event. |
ChannelHandler |
first()
Returns the first
ChannelHandler in this pipeline. |
ChannelHandlerContext |
firstContext()
Returns the context of the first
ChannelHandler in this pipeline. |
ChannelPipeline |
flush()
Request to flush all pending messages via this ChannelOutboundInvoker.
|
<T extends ChannelHandler> |
get(Class<T> handlerType)
Returns the
ChannelHandler of the specified type in this
pipeline. |
ChannelHandler |
get(String name)
Returns the
ChannelHandler with the specified name in this
pipeline. |
ChannelHandler |
last()
Returns the last
ChannelHandler in this pipeline. |
ChannelHandlerContext |
lastContext()
Returns the context of the last
ChannelHandler in this pipeline. |
List<String> |
names()
Returns the
List of the handler names. |
ChannelPipeline |
remove(ChannelHandler handler)
Removes the specified
ChannelHandler from this pipeline. |
<T extends ChannelHandler> |
remove(Class<T> handlerType)
Removes the
ChannelHandler of the specified type from this pipeline. |
ChannelHandler |
remove(String name)
Removes the
ChannelHandler with the specified name from this pipeline. |
ChannelHandler |
removeFirst()
Removes the first
ChannelHandler in this pipeline. |
ChannelHandler |
removeLast()
Removes the last
ChannelHandler in this pipeline. |
ChannelPipeline |
replace(ChannelHandler oldHandler,
String newName,
ChannelHandler newHandler)
Replaces the specified
ChannelHandler with a new handler in this pipeline. |
<T extends ChannelHandler> |
replace(Class<T> oldHandlerType,
String newName,
ChannelHandler newHandler)
Replaces the
ChannelHandler of the specified type with a new handler in this pipeline. |
ChannelHandler |
replace(String oldName,
String newName,
ChannelHandler newHandler)
Replaces the
ChannelHandler of the specified name with a new handler in this pipeline. |
Map<String,ChannelHandler> |
toMap()
Converts this pipeline into an ordered
Map whose keys are
handler names and whose values are handlers. |
bind, bind, close, close, connect, connect, connect, connect, deregister, deregister, disconnect, disconnect, newFailedFuture, newProgressivePromise, newPromise, newSucceededFuture, read, voidPromise, write, write, writeAndFlush, writeAndFlush
forEach, iterator, spliterator
ChannelPipeline addFirst(String name, ChannelHandler handler)
ChannelHandler
at the first position of this pipeline.name
- the name of the handler to insert firsthandler
- the handler to insert firstIllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler is null
ChannelPipeline addFirst(EventExecutorGroup group, String name, ChannelHandler handler)
ChannelHandler
at the first position of this pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
methodsname
- the name of the handler to insert firsthandler
- the handler to insert firstIllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler is null
ChannelPipeline addLast(String name, ChannelHandler handler)
ChannelHandler
at the last position of this pipeline.name
- the name of the handler to appendhandler
- the handler to appendIllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler is null
ChannelPipeline addLast(EventExecutorGroup group, String name, ChannelHandler handler)
ChannelHandler
at the last position of this pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
methodsname
- the name of the handler to appendhandler
- the handler to appendIllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified handler is null
ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler)
ChannelHandler
before an existing handler of this
pipeline.baseName
- the name of the existing handlername
- the name of the handler to insert beforehandler
- the handler to insert beforeNoSuchElementException
- if there's no such entry with the specified baseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler is null
ChannelPipeline addBefore(EventExecutorGroup group, String baseName, String name, ChannelHandler handler)
ChannelHandler
before an existing handler of this
pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
methodsbaseName
- the name of the existing handlername
- the name of the handler to insert beforehandler
- the handler to insert beforeNoSuchElementException
- if there's no such entry with the specified baseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler is null
ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler)
ChannelHandler
after an existing handler of this
pipeline.baseName
- the name of the existing handlername
- the name of the handler to insert afterhandler
- the handler to insert afterNoSuchElementException
- if there's no such entry with the specified baseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler is null
ChannelPipeline addAfter(EventExecutorGroup group, String baseName, String name, ChannelHandler handler)
ChannelHandler
after an existing handler of this
pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
methodsbaseName
- the name of the existing handlername
- the name of the handler to insert afterhandler
- the handler to insert afterNoSuchElementException
- if there's no such entry with the specified baseName
IllegalArgumentException
- if there's an entry with the same name already in the pipelineNullPointerException
- if the specified baseName or handler is null
ChannelPipeline addFirst(ChannelHandler... handlers)
ChannelHandler
s at the first position of this pipeline.handlers
- the handlers to insert firstChannelPipeline addFirst(EventExecutorGroup group, ChannelHandler... handlers)
ChannelHandler
s at the first position of this pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
s
methods.handlers
- the handlers to insert firstChannelPipeline addLast(ChannelHandler... handlers)
ChannelHandler
s at the last position of this pipeline.handlers
- the handlers to insert lastChannelPipeline addLast(EventExecutorGroup group, ChannelHandler... handlers)
ChannelHandler
s at the last position of this pipeline.group
- the EventExecutorGroup
which will be used to execute the ChannelHandler
s
methods.handlers
- the handlers to insert lastChannelPipeline remove(ChannelHandler handler)
ChannelHandler
from this pipeline.handler
- the ChannelHandler
to removeNoSuchElementException
- if there's no such handler in this pipelineNullPointerException
- if the specified handler is null
ChannelHandler remove(String name)
ChannelHandler
with the specified name from this pipeline.name
- the name under which the ChannelHandler
was stored.NoSuchElementException
- if there's no such handler with the specified name in this pipelineNullPointerException
- if the specified name is null
<T extends ChannelHandler> T remove(Class<T> handlerType)
ChannelHandler
of the specified type from this pipeline.T
- the type of the handlerhandlerType
- the type of the handlerNoSuchElementException
- if there's no such handler of the specified type in this pipelineNullPointerException
- if the specified handler type is null
ChannelHandler removeFirst()
ChannelHandler
in this pipeline.NoSuchElementException
- if this pipeline is emptyChannelHandler removeLast()
ChannelHandler
in this pipeline.NoSuchElementException
- if this pipeline is emptyChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler)
ChannelHandler
with a new handler in this pipeline.oldHandler
- the ChannelHandler
to be replacednewName
- the name under which the replacement should be addednewHandler
- the ChannelHandler
which is used as replacementNoSuchElementException
- if the specified old handler does not exist in this pipelineIllegalArgumentException
- if a handler with the specified new name already exists in this
pipeline, except for the handler to be replacedNullPointerException
- if the specified old handler or new handler is
null
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler)
ChannelHandler
of the specified name with a new handler in this pipeline.oldName
- the name of the ChannelHandler
to be replacednewName
- the name under which the replacement should be addednewHandler
- the ChannelHandler
which is used as replacementNoSuchElementException
- if the handler with the specified old name does not exist in this pipelineIllegalArgumentException
- if a handler with the specified new name already exists in this
pipeline, except for the handler to be replacedNullPointerException
- if the specified old handler or new handler is
null
<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler)
ChannelHandler
of the specified type with a new handler in this pipeline.oldHandlerType
- the type of the handler to be removednewName
- the name under which the replacement should be addednewHandler
- the ChannelHandler
which is used as replacementNoSuchElementException
- if the handler of the specified old handler type does not exist
in this pipelineIllegalArgumentException
- if a handler with the specified new name already exists in this
pipeline, except for the handler to be replacedNullPointerException
- if the specified old handler or new handler is
null
ChannelHandler first()
ChannelHandler
in this pipeline.null
if this pipeline is empty.ChannelHandlerContext firstContext()
ChannelHandler
in this pipeline.null
if this pipeline is empty.ChannelHandler last()
ChannelHandler
in this pipeline.null
if this pipeline is empty.ChannelHandlerContext lastContext()
ChannelHandler
in this pipeline.null
if this pipeline is empty.ChannelHandler get(String name)
ChannelHandler
with the specified name in this
pipeline.null
if there's no such handler in this pipeline.<T extends ChannelHandler> T get(Class<T> handlerType)
ChannelHandler
of the specified type in this
pipeline.null
if there's no such handler in this pipeline.ChannelHandlerContext context(ChannelHandler handler)
ChannelHandler
in
this pipeline.null
if there's no such handler in this pipeline.ChannelHandlerContext context(String name)
ChannelHandler
with the
specified name in this pipeline.null
if there's no such handler in this pipeline.ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType)
ChannelHandler
of the
specified type in this pipeline.null
if there's no such handler in this pipeline.Channel channel()
Channel
that this pipeline is attached to.null
if this pipeline is not attached yet.Map<String,ChannelHandler> toMap()
Map
whose keys are
handler names and whose values are handlers.ChannelPipeline fireChannelRegistered()
ChannelInboundInvoker
Channel
was registered to its EventLoop
.
This will result in having the ChannelInboundHandler.channelRegistered(ChannelHandlerContext)
method
called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireChannelRegistered
in interface ChannelInboundInvoker
ChannelPipeline fireChannelUnregistered()
ChannelInboundInvoker
Channel
was unregistered from its EventLoop
.
This will result in having the ChannelInboundHandler.channelUnregistered(ChannelHandlerContext)
method
called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireChannelUnregistered
in interface ChannelInboundInvoker
ChannelPipeline fireChannelActive()
ChannelInboundInvoker
Channel
is active now, which means it is connected.
This will result in having the ChannelInboundHandler.channelActive(ChannelHandlerContext)
method
called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireChannelActive
in interface ChannelInboundInvoker
ChannelPipeline fireChannelInactive()
ChannelInboundInvoker
Channel
is inactive now, which means it is closed.
This will result in having the ChannelInboundHandler.channelInactive(ChannelHandlerContext)
method
called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireChannelInactive
in interface ChannelInboundInvoker
ChannelPipeline fireExceptionCaught(Throwable cause)
ChannelInboundInvoker
Channel
received an Throwable
in one of its inbound operations.
This will result in having the ChannelInboundHandler.exceptionCaught(ChannelHandlerContext, Throwable)
method called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireExceptionCaught
in interface ChannelInboundInvoker
ChannelPipeline fireUserEventTriggered(Object event)
ChannelInboundInvoker
Channel
received an user defined event.
This will result in having the ChannelInboundHandler.userEventTriggered(ChannelHandlerContext, Object)
method called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireUserEventTriggered
in interface ChannelInboundInvoker
ChannelPipeline fireChannelRead(Object msg)
ChannelInboundInvoker
Channel
received a message.
This will result in having the ChannelInboundHandler.channelRead(ChannelHandlerContext, Object)
method called of the next ChannelInboundHandler
contained in the ChannelPipeline
of the
Channel
.fireChannelRead
in interface ChannelInboundInvoker
ChannelPipeline fireChannelReadComplete()
ChannelInboundInvoker
ChannelInboundHandler.channelReadComplete(ChannelHandlerContext)
event to the next ChannelInboundHandler
in the ChannelPipeline
.fireChannelReadComplete
in interface ChannelInboundInvoker
ChannelPipeline fireChannelWritabilityChanged()
ChannelInboundInvoker
ChannelInboundHandler.channelWritabilityChanged(ChannelHandlerContext)
event to the next ChannelInboundHandler
in the ChannelPipeline
.fireChannelWritabilityChanged
in interface ChannelInboundInvoker
ChannelPipeline flush()
ChannelOutboundInvoker
flush
in interface ChannelOutboundInvoker
Copyright © 2008–2024 The Netty Project. All rights reserved.