Interface ChannelPipeline
-
- All Known Implementing Classes:
AbstractCodecEmbedder.EmbeddedChannelPipeline
,DefaultChannelPipeline
public interface ChannelPipeline
A list ofChannelHandler
s which handles or interceptsChannelEvent
s of aChannel
.ChannelPipeline
implements an advanced form of the Intercepting Filter pattern to give a user full control over how an event is handled and how theChannelHandler
s in the pipeline interact with each other.Creation of a pipeline
For each new channel, a new pipeline must be created and attached to the channel. Once attached, the coupling between the channel and the pipeline is permanent; the channel cannot attach another pipeline to it nor detach the current pipeline from it.The recommended way to create a new pipeline is to use the helper methods in
Channels
rather than calling an individual implementation's constructor:import static org.jboss.netty.channel.
Channels
.*;ChannelPipeline
pipeline = pipeline(); // same with Channels.pipeline()How an event flows in a pipeline
The following diagram describes howChannelEvent
s are processed byChannelHandler
s in aChannelPipeline
typically. AChannelEvent
can be handled by either aChannelUpstreamHandler
or aChannelDownstreamHandler
and be forwarded to the closest handler by callingChannelHandlerContext.sendUpstream(ChannelEvent)
orChannelHandlerContext.sendDownstream(ChannelEvent)
. The meaning of the event is interpreted somewhat differently depending on whether it is going upstream or going downstream. Please refer toChannelEvent
for more information.I/O Request via
An upstream event is handled by the upstream handlers in the bottom-up direction as shown on the left side of the diagram. An upstream 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 | | | \|/ | | +----------------------+ +-----------+------------+ | | | Upstream Handler N | | Downstream Handler 1 | | | +----------+-----------+ +-----------+------------+ | | /|\ | | | | \|/ | | +----------+-----------+ +-----------+------------+ | | | Upstream Handler N-1 | | Downstream Handler 2 | | | +----------+-----------+ +-----------+------------+ | | /|\ . | | . . | | [ sendUpstream() ] [ sendDownstream() ] | | [ + INBOUND data ] [ + OUTBOUND data ] | | . . | | . \|/ | | +----------+-----------+ +-----------+------------+ | | | Upstream Handler 2 | | Downstream Handler M-1 | | | +----------+-----------+ +-----------+------------+ | | /|\ | | | | \|/ | | +----------+-----------+ +-----------+------------+ | | | Upstream Handler 1 | | Downstream Handler M | | | +----------+-----------+ +-----------+------------+ | | /|\ | | +-------------+--------------------------+---------------+ | \|/ +-------------+--------------------------+---------------+ | | | | | [ Socket.read() ] [ Socket.write() ] | | | | Netty Internal I/O Threads (Transport Implementation) | +--------------------------------------------------------+InputStream.read(byte[])
. If an upstream event goes beyond the top upstream handler, it is discarded silently.A downstream event is handled by the downstream handler in the top-down direction as shown on the right side of the diagram. A downstream handler usually generates or transforms the outbound traffic such as write requests. If a downstream event goes beyond the bottom downstream handler, it is handled by an I/O thread associated with the
Channel
. The I/O thread often performs the actual output operation such asOutputStream.write(byte[])
.For example, let us assume that we created the following pipeline:
ChannelPipeline
p =Channels
.pipeline(); p.addLast("1", new UpstreamHandlerA()); p.addLast("2", new UpstreamHandlerB()); p.addLast("3", new DownstreamHandlerA()); p.addLast("4", new DownstreamHandlerB()); p.addLast("5", new UpstreamHandlerX());Upstream
means it is an upstream handler. The class whose name starts withDownstream
means it is a downstream handler.In the given example configuration, the handler evaluation order is 1, 2, 3, 4, 5 when an event goes upstream. When an event goes downstream, 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:- 3 and 4 don't implement
ChannelUpstreamHandler
, and therefore the actual evaluation order of an upstream event will be: 1, 2, and 5. - 1, 2, and 5 don't implement
ChannelDownstreamHandler
, and therefore the actual evaluation order of a downstream event will be: 4 and 3. - If 5 extended
SimpleChannelHandler
which implements bothChannelUpstreamHandler
andChannelDownstreamHandler
, the evaluation order of an upstream and a downstream event could be 125 and 543 respectively.
Building a pipeline
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:- Protocol Decoder - translates binary data (e.g.
ChannelBuffer
) into a Java object. - Protocol Encoder - translates a Java object into binary data.
ExecutionHandler
- applies a thread model.- Business Logic Handler - performs the actual business logic (e.g. database access).
ChannelPipeline
pipeline =Channels.pipeline()
; pipeline.addLast("decoder", new MyProtocolDecoder()); pipeline.addLast("encoder", new MyProtocolEncoder()); pipeline.addLast("executor", newExecutionHandler
( newOrderedMemoryAwareThreadPoolExecutor
(16, 1048576, 1048576))); pipeline.addLast("handler", new MyBusinessLogicHandler());Thread safety
A
ChannelHandler
can be added or removed at any time because aChannelPipeline
is thread safe. For example, you can insert aSslHandler
when sensitive information is about to be exchanged, and remove it after the exchange.Pitfall
Due to the internal implementation detail of the current default
ChannelPipeline
, the following code does not work as expected if FirstHandler is the last handler in the pipeline:public class FirstHandler extends
To implement the expected behavior, you have to add SecondHandler before the removal or make sure there is at least one more handler between FirstHandler and SecondHandler.SimpleChannelUpstreamHandler
{@Override
public void messageReceived(ChannelHandlerContext
ctx,MessageEvent
e) { // Remove this handler from the pipeline, ctx.getPipeline().remove(this); // And let SecondHandler handle the current event. ctx.getPipeline().addLast("2nd", new SecondHandler()); ctx.sendUpstream(e); } }
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description void
addAfter(java.lang.String baseName, java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
after an existing handler of this pipeline.void
addBefore(java.lang.String baseName, java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
before an existing handler of this pipeline.void
addFirst(java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
at the first position of this pipeline.void
addLast(java.lang.String name, ChannelHandler handler)
Appends aChannelHandler
at the last position of this pipeline.void
attach(Channel channel, ChannelSink sink)
Attaches this pipeline to the specifiedChannel
andChannelSink
.ChannelFuture
execute(java.lang.Runnable task)
Schedules the specified task to be executed in the I/O thread associated with this pipeline'sChannel
.<T extends ChannelHandler>
Tget(java.lang.Class<T> handlerType)
Returns theChannelHandler
of the specified type in this pipeline.ChannelHandler
get(java.lang.String name)
Returns theChannelHandler
with the specified name in this pipeline.Channel
getChannel()
Returns theChannel
that this pipeline is attached to.ChannelHandlerContext
getContext(java.lang.Class<? extends ChannelHandler> handlerType)
Returns the context object of theChannelHandler
of the specified type in this pipeline.ChannelHandlerContext
getContext(java.lang.String name)
Returns the context object of theChannelHandler
with the specified name in this pipeline.ChannelHandlerContext
getContext(ChannelHandler handler)
Returns the context object of the specifiedChannelHandler
in this pipeline.ChannelHandler
getFirst()
Returns the firstChannelHandler
in this pipeline.ChannelHandler
getLast()
Returns the lastChannelHandler
in this pipeline.java.util.List<java.lang.String>
getNames()
Returns theList
of the handler names.ChannelSink
getSink()
Returns theChannelSink
that this pipeline is attached to.boolean
isAttached()
Returnstrue
if and only if this pipeline is attached to aChannel
.<T extends ChannelHandler>
Tremove(java.lang.Class<T> handlerType)
Removes theChannelHandler
of the specified type from this pipelineChannelHandler
remove(java.lang.String name)
Removes theChannelHandler
with the specified name from this pipeline.void
remove(ChannelHandler handler)
Removes the specifiedChannelHandler
from this pipeline.ChannelHandler
removeFirst()
Removes the firstChannelHandler
in this pipeline.ChannelHandler
removeLast()
Removes the lastChannelHandler
in this pipeline.<T extends ChannelHandler>
Treplace(java.lang.Class<T> oldHandlerType, java.lang.String newName, ChannelHandler newHandler)
Replaces theChannelHandler
of the specified type with a new handler in this pipeline.ChannelHandler
replace(java.lang.String oldName, java.lang.String newName, ChannelHandler newHandler)
Replaces theChannelHandler
of the specified name with a new handler in this pipeline.void
replace(ChannelHandler oldHandler, java.lang.String newName, ChannelHandler newHandler)
Replaces the specifiedChannelHandler
with a new handler in this pipeline.void
sendDownstream(ChannelEvent e)
Sends the specifiedChannelEvent
to the lastChannelDownstreamHandler
in this pipeline.void
sendUpstream(ChannelEvent e)
Sends the specifiedChannelEvent
to the firstChannelUpstreamHandler
in this pipeline.java.util.Map<java.lang.String,ChannelHandler>
toMap()
Converts this pipeline into an orderedMap
whose keys are handler names and whose values are handlers.
-
-
-
Method Detail
-
addFirst
void addFirst(java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
at the first position of this pipeline.- Parameters:
name
- the name of the handler to insert firsthandler
- the handler to insert first- Throws:
java.lang.IllegalArgumentException
- if there's an entry with the same name already in the pipelinejava.lang.NullPointerException
- if the specified name or handler isnull
-
addLast
void addLast(java.lang.String name, ChannelHandler handler)
Appends aChannelHandler
at the last position of this pipeline.- Parameters:
name
- the name of the handler to appendhandler
- the handler to append- Throws:
java.lang.IllegalArgumentException
- if there's an entry with the same name already in the pipelinejava.lang.NullPointerException
- if the specified name or handler isnull
-
addBefore
void addBefore(java.lang.String baseName, java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
before an existing handler of this pipeline.- Parameters:
baseName
- the name of the existing handlername
- the name of the handler to insert beforehandler
- the handler to insert before- Throws:
java.util.NoSuchElementException
- if there's no such entry with the specifiedbaseName
java.lang.IllegalArgumentException
- if there's an entry with the same name already in the pipelinejava.lang.NullPointerException
- if the specified baseName, name, or handler isnull
-
addAfter
void addAfter(java.lang.String baseName, java.lang.String name, ChannelHandler handler)
Inserts aChannelHandler
after an existing handler of this pipeline.- Parameters:
baseName
- the name of the existing handlername
- the name of the handler to insert afterhandler
- the handler to insert after- Throws:
java.util.NoSuchElementException
- if there's no such entry with the specifiedbaseName
java.lang.IllegalArgumentException
- if there's an entry with the same name already in the pipelinejava.lang.NullPointerException
- if the specified baseName, name, or handler isnull
-
remove
void remove(ChannelHandler handler)
Removes the specifiedChannelHandler
from this pipeline.- Throws:
java.util.NoSuchElementException
- if there's no such handler in this pipelinejava.lang.NullPointerException
- if the specified handler isnull
-
remove
ChannelHandler remove(java.lang.String name)
Removes theChannelHandler
with the specified name from this pipeline.- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if there's no such handler with the specified name in this pipelinejava.lang.NullPointerException
- if the specified name isnull
-
remove
<T extends ChannelHandler> T remove(java.lang.Class<T> handlerType)
Removes theChannelHandler
of the specified type from this pipeline- Type Parameters:
T
- the type of the handler- Parameters:
handlerType
- the type of the handler- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if there's no such handler of the specified type in this pipelinejava.lang.NullPointerException
- if the specified handler type isnull
-
removeFirst
ChannelHandler removeFirst()
Removes the firstChannelHandler
in this pipeline.- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if this pipeline is empty
-
removeLast
ChannelHandler removeLast()
Removes the lastChannelHandler
in this pipeline.- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if this pipeline is empty
-
replace
void replace(ChannelHandler oldHandler, java.lang.String newName, ChannelHandler newHandler)
Replaces the specifiedChannelHandler
with a new handler in this pipeline.- Throws:
java.util.NoSuchElementException
- if the specified old handler does not exist in this pipelinejava.lang.IllegalArgumentException
- if a handler with the specified new name already exists in this pipeline, except for the handler to be replacedjava.lang.NullPointerException
- if the specified old handler, new name, or new handler isnull
-
replace
ChannelHandler replace(java.lang.String oldName, java.lang.String newName, ChannelHandler newHandler)
Replaces theChannelHandler
of the specified name with a new handler in this pipeline.- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if the handler with the specified old name does not exist in this pipelinejava.lang.IllegalArgumentException
- if a handler with the specified new name already exists in this pipeline, except for the handler to be replacedjava.lang.NullPointerException
- if the specified old handler, new name, or new handler isnull
-
replace
<T extends ChannelHandler> T replace(java.lang.Class<T> oldHandlerType, java.lang.String newName, ChannelHandler newHandler)
Replaces theChannelHandler
of the specified type with a new handler in this pipeline.- Returns:
- the removed handler
- Throws:
java.util.NoSuchElementException
- if the handler of the specified old handler type does not exist in this pipelinejava.lang.IllegalArgumentException
- if a handler with the specified new name already exists in this pipeline, except for the handler to be replacedjava.lang.NullPointerException
- if the specified old handler, new name, or new handler isnull
-
getFirst
ChannelHandler getFirst()
Returns the firstChannelHandler
in this pipeline.- Returns:
- the first handler.
null
if this pipeline is empty.
-
getLast
ChannelHandler getLast()
Returns the lastChannelHandler
in this pipeline.- Returns:
- the last handler.
null
if this pipeline is empty.
-
get
ChannelHandler get(java.lang.String name)
Returns theChannelHandler
with the specified name in this pipeline.- Returns:
- the handler with the specified name.
null
if there's no such handler in this pipeline.
-
get
<T extends ChannelHandler> T get(java.lang.Class<T> handlerType)
Returns theChannelHandler
of the specified type in this pipeline.- Returns:
- the handler of the specified handler type.
null
if there's no such handler in this pipeline.
-
getContext
ChannelHandlerContext getContext(ChannelHandler handler)
Returns the context object of the specifiedChannelHandler
in this pipeline.- Returns:
- the context object of the specified handler.
null
if there's no such handler in this pipeline.
-
getContext
ChannelHandlerContext getContext(java.lang.String name)
Returns the context object of theChannelHandler
with the specified name in this pipeline.- Returns:
- the context object of the handler with the specified name.
null
if there's no such handler in this pipeline.
-
getContext
ChannelHandlerContext getContext(java.lang.Class<? extends ChannelHandler> handlerType)
Returns the context object of theChannelHandler
of the specified type in this pipeline.- Returns:
- the context object of the handler of the specified type.
null
if there's no such handler in this pipeline.
-
sendUpstream
void sendUpstream(ChannelEvent e)
Sends the specifiedChannelEvent
to the firstChannelUpstreamHandler
in this pipeline.- Throws:
java.lang.NullPointerException
- if the specified event isnull
-
sendDownstream
void sendDownstream(ChannelEvent e)
Sends the specifiedChannelEvent
to the lastChannelDownstreamHandler
in this pipeline.- Throws:
java.lang.NullPointerException
- if the specified event isnull
-
execute
ChannelFuture execute(java.lang.Runnable task)
Schedules the specified task to be executed in the I/O thread associated with this pipeline'sChannel
.
-
getChannel
Channel getChannel()
Returns theChannel
that this pipeline is attached to.- Returns:
- the channel.
null
if this pipeline is not attached yet.
-
getSink
ChannelSink getSink()
Returns theChannelSink
that this pipeline is attached to.- Returns:
- the sink.
null
if this pipeline is not attached yet.
-
attach
void attach(Channel channel, ChannelSink sink)
Attaches this pipeline to the specifiedChannel
andChannelSink
. Once a pipeline is attached, it can't be detached nor attached again.- Throws:
java.lang.IllegalStateException
- if this pipeline is attached already
-
isAttached
boolean isAttached()
Returnstrue
if and only if this pipeline is attached to aChannel
.
-
getNames
java.util.List<java.lang.String> getNames()
Returns theList
of the handler names.
-
toMap
java.util.Map<java.lang.String,ChannelHandler> toMap()
Converts this pipeline into an orderedMap
whose keys are handler names and whose values are handlers.
-
-