Interface ChannelHandler
-
- All Known Subinterfaces:
ChannelDownstreamHandler
,ChannelUpstreamHandler
,LifeCycleAwareChannelHandler
- All Known Implementing Classes:
AbstractCodecEmbedder.EmbeddedChannelSink
,AbstractTrafficShapingHandler
,AutobahnServerHandler
,Base64Decoder
,Base64Encoder
,BigIntegerDecoder
,BlockingReadHandler
,BufferedWriteHandler
,ChannelTrafficShapingHandler
,ChunkedWriteHandler
,CompatibleMarshallingDecoder
,CompatibleMarshallingEncoder
,CompatibleObjectEncoder
,DelimiterBasedFrameDecoder
,DiscardClientHandler
,DiscardServerHandler
,EchoClientHandler
,EchoServerHandler
,ExecutionHandler
,FactorialClientHandler
,FactorialServerHandler
,FixedLengthFrameDecoder
,FrameDecoder
,GlobalChannelTrafficShapingHandler
,GlobalTrafficShapingHandler
,HexDumpProxyInboundHandler
,HexDumpProxyInboundHandler.OutboundHandler
,HttpChunkAggregator
,HttpClientCodec
,HttpClientCodec.Decoder
,HttpClientCodec.Encoder
,HttpContentCompressor
,HttpContentDecoder
,HttpContentDecompressor
,HttpContentEncoder
,HttpHelloWorldServerHandler
,HttpMessageDecoder
,HttpMessageEncoder
,HttpRequestDecoder
,HttpRequestEncoder
,HttpResponseDecoder
,HttpResponseEncoder
,HttpServerCodec
,HttpSnoopClientHandler
,HttpSnoopServerHandler
,HttpStaticFileServerHandler
,HttpTunnelingClientSocketChannel.ServletChannelHandler
,HttpTunnelingServlet.OutboundConnectionHandler
,HttpUploadClientHandler
,HttpUploadServerHandler
,IdleStateAwareChannelHandler
,IdleStateAwareChannelUpstreamHandler
,IdleStateHandler
,IpFilteringHandlerImpl
,IpFilterRuleHandler
,JdkZlibEncoder
,LengthFieldBasedFrameDecoder
,LengthFieldPrepender
,LineBasedFrameDecoder
,LocalTimeClientHandler
,LocalTimeServerHandler
,LoggingHandler
,MarshallingDecoder
,MarshallingEncoder
,NumberEncoder
,ObjectDecoder
,ObjectEchoClientHandler
,ObjectEchoServerHandler
,ObjectEncoder
,OneIpFilterHandler
,OneToOneDecoder
,OneToOneEncoder
,OneToOneStrictEncoder
,PortUnificationServerHandler
,ProtobufDecoder
,ProtobufEncoder
,ProtobufVarint32FrameDecoder
,ProtobufVarint32LengthFieldPrepender
,QuoteOfTheMomentClientHandler
,QuoteOfTheMomentServerHandler
,ReadTimeoutHandler
,ReplayingDecoder
,RtspMessageDecoder
,RtspMessageEncoder
,RtspRequestDecoder
,RtspRequestEncoder
,RtspResponseDecoder
,RtspResponseEncoder
,SecureChatClientHandler
,SecureChatServerHandler
,ServerBootstrap.Binder
,SimpleChannelDownstreamHandler
,SimpleChannelHandler
,SimpleChannelUpstreamHandler
,SocksAuthRequestDecoder
,SocksAuthResponseDecoder
,SocksCmdRequestDecoder
,SocksCmdResponseDecoder
,SocksInitRequestDecoder
,SocksInitResponseDecoder
,SocksMessageEncoder
,SpdyFrameCodec
,SpdyHttpCodec
,SpdyHttpDecoder
,SpdyHttpEncoder
,SpdyHttpResponseStreamIdHandler
,SpdyOrHttpChooser
,SpdySessionHandler
,SslHandler
,StringDecoder
,StringEncoder
,TelnetClientHandler
,TelnetServerHandler
,UptimeClientHandler
,WebSocket00FrameDecoder
,WebSocket00FrameEncoder
,WebSocket07FrameDecoder
,WebSocket07FrameEncoder
,WebSocket08FrameDecoder
,WebSocket08FrameEncoder
,WebSocket13FrameDecoder
,WebSocket13FrameEncoder
,WebSocketClientHandler
,WebSocketFrameAggregator
,WebSocketServerHandler
,WebSocketServerProtocolHandler
,WebSocketServerProtocolHandshakeHandler
,WriteTimeoutHandler
,ZlibDecoder
,ZlibEncoder
public interface ChannelHandler
Handles or intercepts aChannelEvent
, and sends aChannelEvent
to the next handler in aChannelPipeline
.Sub-types
ChannelHandler
itself does not provide any method. To handle aChannelEvent
you need to implement its sub-interfaces. There are two sub-interfaces which handles a received event, one for upstream events and the other for downstream events:ChannelUpstreamHandler
handles and intercepts an upstreamChannelEvent
.ChannelDownstreamHandler
handles and intercepts a downstreamChannelEvent
.
The context object
A
ChannelHandler
is provided with aChannelHandlerContext
object. AChannelHandler
is supposed to interact with theChannelPipeline
it belongs to via a context object. Using the context object, theChannelHandler
can pass events upstream or downstream, modify the pipeline dynamically, or store the information (attachment) which is specific to the handler.State management
AChannelHandler
often needs to store some stateful information. The simplest and recommended approach is to use member variables:public class DataServerHandler extends
Because the handler instance has a state variable which is dedicated to one connection, you have to create a new handler instance for each new channel to avoid a race condition where a unauthenticated client can get the confidential information:SimpleChannelHandler
{ private boolean loggedIn;@Override
public void messageReceived(ChannelHandlerContext
ctx,MessageEvent
e) {Channel
ch = e.getChannel(); Object o = e.getMessage(); if (o instanceof LoginMessage) { authenticate((LoginMessage) o); loggedIn = true; } else (o instanceof GetDataMessage) { if (loggedIn) { ch.write(fetchSecret((GetDataMessage) o)); } else { fail(); } } } ... }// Create a new handler instance per channel. // See
Bootstrap.setPipelineFactory(ChannelPipelineFactory)
. public class DataServerPipelineFactory implementsChannelPipelineFactory
{ publicChannelPipeline
getPipeline() { returnChannels
.pipeline(new DataServerHandler()); } }Using an attachment
Although it's recommended to use member variables to store the state of a handler, for some reason you might not want to create many handler instances. In such a case, you can use an attachment which is provided byChannelHandlerContext
:@Sharable
public class DataServerHandler extendsSimpleChannelHandler
{@Override
public void messageReceived(ChannelHandlerContext
ctx,MessageEvent
e) {Channel
ch = e.getChannel(); Object o = e.getMessage(); if (o instanceof LoginMessage) { authenticate((LoginMessage) o); ctx.setAttachment(true); } else (o instanceof GetDataMessage) { if (Boolean.TRUE.equals(ctx.getAttachment())) { ch.write(fetchSecret((GetDataMessage) o)); } else { fail(); } } } ... }public class DataServerPipelineFactory implements
ChannelPipelineFactory
{ private static final DataServerHandler SHARED = new DataServerHandler(); publicChannelPipeline
getPipeline() { returnChannels
.pipeline(SHARED); } }Using a
If you have a state variable which needs to be accessed either from other handlers or outside handlers, you can useChannelLocal
ChannelLocal
:public final class DataServerState { public static final
ChannelLocal
<Boolean> loggedIn = newChannelLocal
<>() { protected Boolean initialValue(Channel channel) { return false; } } ... }@Sharable
public class DataServerHandler extendsSimpleChannelHandler
{@Override
public void messageReceived(ChannelHandlerContext
ctx,MessageEvent
e) { Channel ch = e.getChannel(); Object o = e.getMessage(); if (o instanceof LoginMessage) { authenticate((LoginMessage) o); DataServerState.loggedIn.set(ch, true); } else (o instanceof GetDataMessage) { if (DataServerState.loggedIn.get(ch)) { ctx.getChannel().write(fetchSecret((GetDataMessage) o)); } else { fail(); } } } ... } // Print the remote addresses of the authenticated clients:ChannelGroup
allClientChannels = ...; for (Channel
ch: allClientChannels) { if (DataServerState.loggedIn.get(ch)) { System.out.println(ch.getRemoteAddress()); } }The
@Sharable
annotationIn the examples above which used an attachment or a
ChannelLocal
, you might have noticed the@Sharable
annotation.If a
ChannelHandler
is annotated with the@Sharable
annotation, it means you can create an instance of the handler just once and add it to one or moreChannelPipeline
s multiple times without a race condition.If this annotation is not specified, you have to create a new handler instance every time you add it to a pipeline because it has unshared state such as member variables.
This annotation is provided for documentation purpose, just like the JCIP annotations.
Additional resources worth reading
Please refer to the
ChannelEvent
andChannelPipeline
to find out what a upstream event and a downstream event are, what fundamental differences they have, and how they flow in a pipeline.
-
-
Nested Class Summary
Nested Classes Modifier and Type Interface Description static interface
ChannelHandler.Sharable
Indicates that the same instance of the annotatedChannelHandler
can be added to one or moreChannelPipeline
s multiple times without a race condition.
-