-
- All Superinterfaces:
ChannelInboundInvoker,ChannelOutboundInvoker,FuturePromiseFactory,Iterable<Map.Entry<String,ChannelHandler>>
- All Known Implementing Classes:
AbstractChannel.DefaultAbstractChannelPipeline,DefaultChannelPipeline
public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Map.Entry<String,ChannelHandler>>
A list ofChannelHandlers which handles or intercepts inbound events and outbound operations of aChannel.ChannelPipelineimplements an advanced form of the Intercepting Filter pattern to give a user full control over how an event is handled and how theChannelHandlers in a pipeline interact with each other.Creation of a pipeline
Each channel has its own pipeline and it is created automatically when a new channel is created.How an event flows in a pipeline
The following diagram describes how I/O events are processed byChannelHandlers in aChannelPipelinetypically. An I/O event is handled by aChannelHandler(which may handle inbound or / and outbound events) and be forwarded to its closest handler by calling the event propagation methods defined inChannelHandlerContext, such asChannelHandlerContext.fireChannelRead(Object)andChannelOutboundInvoker.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 asChannelorChannelHandlerContext| +---------------------------------------------------+---------------+ | 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 asSocketChannel.write(ByteBuffer).For example, let us assume that we created the following pipeline:
In the example above, the class whose name starts withChannelPipelinep = ...; 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());Inboundmeans it is an inbound handler. The class whose name starts withOutboundmeans 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,
ChannelPipelineskips the evaluation of certain handlers to shorten the stack depth:- 3 and 4 don't implement inbound handling methods of
ChannelHandler, and therefore the actual evaluation order of an inbound event will be: 1, 2, and 5. - 1 and 2 don't implement outbound handling methods of
ChannelHandler, and therefore the actual evaluation order of an outbound event will be: 5, 4, and 3. - If 5 implements both inbound and outbound handling methods of
ChannelHandler, the evaluation order of an inbound and a outbound event could be 125 and 543 respectively.
Forwarding an event to the next handler
As you might noticed in the diagram shows, a handler has to invoke the event propagation methods inChannelHandlerContextto forward an event to its next handler. Those methods include:- Inbound event propagation methods:
ChannelHandlerContext.fireChannelRegistered()ChannelHandlerContext.fireChannelActive()ChannelHandlerContext.fireChannelRead(Object)ChannelHandlerContext.fireChannelReadComplete()ChannelHandlerContext.fireChannelExceptionCaught(Throwable)ChannelHandlerContext.fireChannelInboundEvent(Object)ChannelHandlerContext.fireChannelWritabilityChanged()ChannelHandlerContext.fireChannelInactive()ChannelHandlerContext.fireChannelShutdown(ChannelShutdownDirection)ChannelHandlerContext.fireChannelUnregistered()
- Outbound event propagation methods:
ChannelOutboundInvoker.bind(SocketAddress)ChannelOutboundInvoker.connect(SocketAddress, SocketAddress)ChannelOutboundInvoker.write(Object)ChannelHandlerContext.flush()ChannelHandlerContext.read()ChannelOutboundInvoker.disconnect()ChannelOutboundInvoker.close()ChannelOutboundInvoker.shutdown(ChannelShutdownDirection)ChannelOutboundInvoker.sendOutboundEvent(Object)ChannelOutboundInvoker.deregister()
public class MyInboundHandler implements
ChannelHandler{@Overridepublic void channelActive(ChannelHandlerContextctx) { System.out.println("Connected!"); ctx.fireChannelActive(); } } public class MyOutboundHandler implementsChannelHandler{@Overridepublic Future<Void> close(ChannelHandlerContextctx) { System.out.println("Closing .."); return ctx.close(); } }Building a pipeline
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:- Protocol Decoder - translates binary data (e.g.
Buffer) into a Java object. - Protocol Encoder - translates a Java object into binary data.
- Business Logic Handler - performs the actual business logic (e.g. database access).
...
ChannelPipelinepipeline = ch.pipeline(); pipeline.addLast("decoder", new MyProtocolDecoder()); pipeline.addLast("encoder", new MyProtocolEncoder()); // If your business logic does block or take a lot of time you should offload the work to an extra //Executorto ensure you don't block theEventLoop. pipeline.addLast("handler", new MyBusinessLogicHandler());Thread safety
A
ChannelHandlercan be added or removed at any time because aChannelPipelineis thread safe. For example, you can insert an encryption handler when sensitive information is about to be exchanged, and remove it after the exchange.
-
-
Method Summary
All Methods Instance Methods Abstract Methods Default Methods Modifier and Type Method Description ChannelPipelineaddAfter(String baseName, String name, ChannelHandler handler)Inserts aChannelHandlerafter an existing handler of this pipeline.ChannelPipelineaddBefore(String baseName, String name, ChannelHandler handler)Inserts aChannelHandlerbefore an existing handler of this pipeline.ChannelPipelineaddFirst(ChannelHandler... handlers)InsertsChannelHandlers at the first position of this pipeline.ChannelPipelineaddFirst(String name, ChannelHandler handler)Inserts aChannelHandlerat the first position of this pipeline.ChannelPipelineaddLast(ChannelHandler... handlers)InsertsChannelHandlers at the last position of this pipeline.ChannelPipelineaddLast(String name, ChannelHandler handler)Appends aChannelHandlerat the last position of this pipeline.Channelchannel()Returns theChannelthat this pipeline is attached to.ChannelHandlerContextcontext(ChannelHandler handler)Returns the context object of the specifiedChannelHandlerin this pipeline.ChannelHandlerContextcontext(Class<? extends ChannelHandler> handlerType)Returns the context object of theChannelHandlerof the specified type in this pipeline.ChannelHandlerContextcontext(String name)Returns the context object of theChannelHandlerwith the specified name in this pipeline.ChannelPipelinefireChannelActive()AChannelis active now, which means it is connected.ChannelPipelinefireChannelExceptionCaught(Throwable cause)ChannelPipelinefireChannelInactive()AChannelis inactive now, which means it is closed.ChannelPipelinefireChannelInboundEvent(Object event)AChannelreceived a custom defined inbound event.ChannelPipelinefireChannelRead(Object msg)AChannelreceived a message.ChannelPipelinefireChannelReadComplete()Triggers anChannelHandler.channelReadComplete(ChannelHandlerContext)event to the nextChannelHandlerin theChannelPipeline.ChannelPipelinefireChannelRegistered()ChannelPipelinefireChannelShutdown(ChannelShutdownDirection direction)AChannelwas shutdown in a specific direction.ChannelPipelinefireChannelUnregistered()ChannelPipelinefireChannelWritabilityChanged()Triggers anChannelHandler.channelWritabilityChanged(ChannelHandlerContext)event to the nextChannelHandlerin theChannelPipeline.default ChannelHandlerfirst()Returns the firstChannelHandlerin this pipeline.ChannelHandlerContextfirstContext()Returns the context of the firstChannelHandlerin this pipeline.ChannelPipelineflush()Request to flush all pending messages via this ChannelOutboundInvoker.<T extends ChannelHandler>
Tget(Class<T> handlerType)Returns theChannelHandlerof the specified type in this pipeline.ChannelHandlerget(String name)Returns theChannelHandlerwith the specified name in this pipeline.default booleanisEmpty()default ChannelHandlerlast()Returns the lastChannelHandlerin this pipeline.ChannelHandlerContextlastContext()Returns the context of the lastChannelHandlerin this pipeline.default List<String>names()Returns theListof the handler names.longpendingOutboundBytes()The number of the outbound bytes that are buffered / queued in thisChannelPipeline.default ChannelPipelineremove(ChannelHandler handler)Removes the specifiedChannelHandlerfrom this pipeline.default <T extends ChannelHandler>
Tremove(Class<T> handlerType)Removes theChannelHandlerof the specified type from this pipeline.default ChannelHandlerremove(String name)Removes theChannelHandlerwith the specified name from this pipeline.ChannelHandlerremoveFirst()Removes the firstChannelHandlerin this pipeline.<T extends ChannelHandler>
TremoveIfExists(ChannelHandler handler)Removes the specifiedChannelHandlerfrom this pipeline if it exists<T extends ChannelHandler>
TremoveIfExists(Class<T> handlerType)Removes theChannelHandlerof the specified type from this pipeline if it exists.<T extends ChannelHandler>
TremoveIfExists(String name)Removes theChannelHandlerwith the specified name from this pipeline if it exists.ChannelHandlerremoveLast()Removes the lastChannelHandlerin this pipeline.ChannelPipelinereplace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler)Replaces the specifiedChannelHandlerwith a new handler in this pipeline.<T extends ChannelHandler>
Treplace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler)Replaces theChannelHandlerof the specified type with a new handler in this pipeline.ChannelHandlerreplace(String oldName, String newName, ChannelHandler newHandler)Replaces theChannelHandlerof the specified name with a new handler in this pipeline.Map<String,ChannelHandler>toMap()Converts this pipeline into an orderedMapwhose keys are handler names and whose values are handlers.-
Methods inherited from interface io.netty5.channel.ChannelOutboundInvoker
bind, close, connect, connect, deregister, disconnect, executor, newFailedFuture, newPromise, newSucceededFuture, newSucceededFuture, read, register, sendOutboundEvent, shutdown, write, writeAndFlush
-
Methods inherited from interface java.lang.Iterable
forEach, iterator, spliterator
-
-
-
-
Method Detail
-
addFirst
ChannelPipeline addFirst(String name, ChannelHandler handler)
Inserts aChannelHandlerat the first position of this pipeline.- Parameters:
name- the name of the handler to insert firsthandler- the handler to insert first- Throws:
IllegalArgumentException- if there's an entry with the same name already in the pipelineNullPointerException- if the specified handler isnull
-
addLast
ChannelPipeline addLast(String name, ChannelHandler handler)
Appends aChannelHandlerat the last position of this pipeline.- Parameters:
name- the name of the handler to appendhandler- the handler to append- Throws:
IllegalArgumentException- if there's an entry with the same name already in the pipelineNullPointerException- if the specified handler isnull
-
addBefore
ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler)
Inserts aChannelHandlerbefore 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:
NoSuchElementException- if there's no such entry with the specifiedbaseNameIllegalArgumentException- if there's an entry with the same name already in the pipelineNullPointerException- if the specified baseName or handler isnull
-
addAfter
ChannelPipeline addAfter(String baseName, String name, ChannelHandler handler)
Inserts aChannelHandlerafter 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:
NoSuchElementException- if there's no such entry with the specifiedbaseNameIllegalArgumentException- if there's an entry with the same name already in the pipelineNullPointerException- if the specified baseName or handler isnull
-
addFirst
ChannelPipeline addFirst(ChannelHandler... handlers)
InsertsChannelHandlers at the first position of this pipeline.nullhandlers will be skipped.- Parameters:
handlers- the handlers to insert first
-
addLast
ChannelPipeline addLast(ChannelHandler... handlers)
InsertsChannelHandlers at the last position of this pipeline.nullhandlers will be skipped.- Parameters:
handlers- the handlers to insert last
-
remove
default ChannelPipeline remove(ChannelHandler handler)
Removes the specifiedChannelHandlerfrom this pipeline.- Parameters:
handler- theChannelHandlerto remove- Throws:
NoSuchElementException- if there's no such handler in this pipelineNullPointerException- if the specified handler isnull
-
remove
default ChannelHandler remove(String name)
Removes theChannelHandlerwith the specified name from this pipeline.- Parameters:
name- the name under which theChannelHandlerwas stored.- Returns:
- the removed handler
- Throws:
NoSuchElementException- if there's no such handler with the specified name in this pipelineNullPointerException- if the specified name isnull
-
remove
default <T extends ChannelHandler> T remove(Class<T> handlerType)
Removes theChannelHandlerof 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:
NoSuchElementException- if there's no such handler of the specified type in this pipelineNullPointerException- if the specified handler type isnull
-
removeIfExists
<T extends ChannelHandler> T removeIfExists(String name)
Removes theChannelHandlerwith the specified name from this pipeline if it exists.- Parameters:
name- the name under which theChannelHandlerwas stored.- Returns:
- the removed handler
- Throws:
NoSuchElementException- if there's no such handler with the specified name in this pipelineNullPointerException- if the specified name isnull
-
removeIfExists
<T extends ChannelHandler> T removeIfExists(Class<T> handlerType)
Removes theChannelHandlerof the specified type from this pipeline if it exists.- Type Parameters:
T- the type of the handler- Parameters:
handlerType- the type of the handler- Returns:
- the removed handler or
nullif it didn't exist. - Throws:
NullPointerException- if the specified handler type isnull
-
removeIfExists
<T extends ChannelHandler> T removeIfExists(ChannelHandler handler)
Removes the specifiedChannelHandlerfrom this pipeline if it exists- Parameters:
handler- theChannelHandlerto remove- Returns:
- the removed handler or
nullif it didn't exist. - Throws:
NullPointerException- if the specified handler isnull
-
removeFirst
ChannelHandler removeFirst()
Removes the firstChannelHandlerin this pipeline.- Returns:
- the removed handler
- Throws:
NoSuchElementException- if this pipeline is empty
-
removeLast
ChannelHandler removeLast()
Removes the lastChannelHandlerin this pipeline.- Returns:
- the removed handler
- Throws:
NoSuchElementException- if this pipeline is empty
-
replace
ChannelPipeline replace(ChannelHandler oldHandler, String newName, ChannelHandler newHandler)
Replaces the specifiedChannelHandlerwith a new handler in this pipeline.- Parameters:
oldHandler- theChannelHandlerto be replacednewName- the name under which the replacement should be addednewHandler- theChannelHandlerwhich is used as replacement- Returns:
- itself
- Throws:
NoSuchElementException- 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 isnull
-
replace
ChannelHandler replace(String oldName, String newName, ChannelHandler newHandler)
Replaces theChannelHandlerof the specified name with a new handler in this pipeline.- Parameters:
oldName- the name of theChannelHandlerto be replacednewName- the name under which the replacement should be addednewHandler- theChannelHandlerwhich is used as replacement- Returns:
- the removed handler
- Throws:
NoSuchElementException- 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 isnull
-
replace
<T extends ChannelHandler> T replace(Class<T> oldHandlerType, String newName, ChannelHandler newHandler)
Replaces theChannelHandlerof the specified type with a new handler in this pipeline.- Parameters:
oldHandlerType- the type of the handler to be removednewName- the name under which the replacement should be addednewHandler- theChannelHandlerwhich is used as replacement- Returns:
- the removed handler
- Throws:
NoSuchElementException- 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 isnull
-
first
default ChannelHandler first()
Returns the firstChannelHandlerin this pipeline.- Returns:
- the first handler.
nullif this pipeline is empty.
-
firstContext
ChannelHandlerContext firstContext()
Returns the context of the firstChannelHandlerin this pipeline.- Returns:
- the context of the first handler.
nullif this pipeline is empty.
-
last
default ChannelHandler last()
Returns the lastChannelHandlerin this pipeline.- Returns:
- the last handler.
nullif this pipeline is empty.
-
lastContext
ChannelHandlerContext lastContext()
Returns the context of the lastChannelHandlerin this pipeline.- Returns:
- the context of the last handler.
nullif this pipeline is empty.
-
isEmpty
default boolean isEmpty()
-
get
ChannelHandler get(String name)
Returns theChannelHandlerwith the specified name in this pipeline.- Returns:
- the handler with the specified name.
nullif there's no such handler in this pipeline.
-
get
<T extends ChannelHandler> T get(Class<T> handlerType)
Returns theChannelHandlerof the specified type in this pipeline.- Returns:
- the handler of the specified handler type.
nullif there's no such handler in this pipeline.
-
context
ChannelHandlerContext context(ChannelHandler handler)
Returns the context object of the specifiedChannelHandlerin this pipeline.- Returns:
- the context object of the specified handler.
nullif there's no such handler in this pipeline.
-
context
ChannelHandlerContext context(String name)
Returns the context object of theChannelHandlerwith the specified name in this pipeline.- Returns:
- the context object of the handler with the specified name.
nullif there's no such handler in this pipeline.
-
context
ChannelHandlerContext context(Class<? extends ChannelHandler> handlerType)
Returns the context object of theChannelHandlerof the specified type in this pipeline.- Returns:
- the context object of the handler of the specified type.
nullif there's no such handler in this pipeline.
-
channel
Channel channel()
Returns theChannelthat this pipeline is attached to.- Returns:
- the channel.
nullif this pipeline is not attached yet.
-
toMap
Map<String,ChannelHandler> toMap()
Converts this pipeline into an orderedMapwhose keys are handler names and whose values are handlers.
-
fireChannelRegistered
ChannelPipeline fireChannelRegistered()
Description copied from interface:ChannelInboundInvokerAChannelwas registered to itsEventLoop. This will result in having theChannelHandler.channelRegistered(ChannelHandlerContext)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelRegisteredin interfaceChannelInboundInvoker
-
fireChannelUnregistered
ChannelPipeline fireChannelUnregistered()
Description copied from interface:ChannelInboundInvokerAChannelwas unregistered from itsEventLoop. This will result in having theChannelHandler.channelUnregistered(ChannelHandlerContext)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelUnregisteredin interfaceChannelInboundInvoker
-
fireChannelActive
ChannelPipeline fireChannelActive()
Description copied from interface:ChannelInboundInvokerAChannelis active now, which means it is connected. This will result in having theChannelHandler.channelActive(ChannelHandlerContext)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelActivein interfaceChannelInboundInvoker
-
fireChannelInactive
ChannelPipeline fireChannelInactive()
Description copied from interface:ChannelInboundInvokerAChannelis inactive now, which means it is closed. This will result in having theChannelHandler.channelInactive(ChannelHandlerContext)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelInactivein interfaceChannelInboundInvoker
-
fireChannelShutdown
ChannelPipeline fireChannelShutdown(ChannelShutdownDirection direction)
Description copied from interface:ChannelInboundInvokerAChannelwas shutdown in a specific direction. This will result in having theChannelHandler.channelShutdown(ChannelHandlerContext, ChannelShutdownDirection)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelShutdownin interfaceChannelInboundInvoker
-
fireChannelExceptionCaught
ChannelPipeline fireChannelExceptionCaught(Throwable cause)
Description copied from interface:ChannelInboundInvokerAChannelreceived anThrowablein one of its inbound operations. This will result in having theChannelHandler.channelExceptionCaught(ChannelHandlerContext, Throwable)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelExceptionCaughtin interfaceChannelInboundInvoker
-
fireChannelInboundEvent
ChannelPipeline fireChannelInboundEvent(Object event)
Description copied from interface:ChannelInboundInvokerAChannelreceived a custom defined inbound event. This will result in having theChannelHandler.channelInboundEvent(ChannelHandlerContext, Object)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelInboundEventin interfaceChannelInboundInvoker
-
fireChannelRead
ChannelPipeline fireChannelRead(Object msg)
Description copied from interface:ChannelInboundInvokerAChannelreceived a message. This will result in having theChannelHandler.channelRead(ChannelHandlerContext, Object)method called of the nextChannelHandlercontained in theChannelPipelineof theChannel.- Specified by:
fireChannelReadin interfaceChannelInboundInvoker
-
fireChannelReadComplete
ChannelPipeline fireChannelReadComplete()
Description copied from interface:ChannelInboundInvokerTriggers anChannelHandler.channelReadComplete(ChannelHandlerContext)event to the nextChannelHandlerin theChannelPipeline.- Specified by:
fireChannelReadCompletein interfaceChannelInboundInvoker
-
fireChannelWritabilityChanged
ChannelPipeline fireChannelWritabilityChanged()
Description copied from interface:ChannelInboundInvokerTriggers anChannelHandler.channelWritabilityChanged(ChannelHandlerContext)event to the nextChannelHandlerin theChannelPipeline.- Specified by:
fireChannelWritabilityChangedin interfaceChannelInboundInvoker
-
flush
ChannelPipeline flush()
Description copied from interface:ChannelOutboundInvokerRequest to flush all pending messages via this ChannelOutboundInvoker.- Specified by:
flushin interfaceChannelOutboundInvoker
-
pendingOutboundBytes
long pendingOutboundBytes()
The number of the outbound bytes that are buffered / queued in thisChannelPipeline. This number will affect the writability of theChanneltogether the buffered / queued bytes in theChannelitself.- Returns:
- the number of buffered / queued bytes.
-
-