Interface ChannelHandler
- All Known Subinterfaces:
ChannelInboundHandler, ChannelOutboundHandler, WebSocketFrameDecoder, WebSocketFrameEncoder
- All Known Implementing Classes:
AbstractBinaryMemcacheDecoder, AbstractBinaryMemcacheEncoder, AbstractMemcacheObjectAggregator, AbstractMemcacheObjectDecoder, AbstractMemcacheObjectEncoder, AbstractRemoteAddressFilter, AbstractSniHandler, AbstractTrafficShapingHandler, ApplicationProtocolNegotiationHandler, Base64Decoder, Base64Encoder, BinaryMemcacheClientCodec, BinaryMemcacheObjectAggregator, BinaryMemcacheRequestDecoder, BinaryMemcacheRequestEncoder, BinaryMemcacheResponseDecoder, BinaryMemcacheResponseEncoder, BinaryMemcacheServerCodec, BrotliDecoder, BrotliEncoder, ByteArrayDecoder, ByteArrayEncoder, ByteToMessageCodec, ByteToMessageDecoder, Bzip2Decoder, Bzip2Encoder, ChannelDuplexHandler, ChannelHandlerAdapter, ChannelInboundHandlerAdapter, ChannelInitializer, ChannelOutboundHandlerAdapter, ChannelTrafficShapingHandler, ChunkedWriteHandler, CleartextHttp2ServerUpgradeHandler, CombinedChannelDuplexHandler, CompatibleMarshallingDecoder, CompatibleMarshallingEncoder, CompatibleObjectEncoder, CorsHandler, DatagramDnsQueryDecoder, DatagramDnsQueryEncoder, DatagramDnsResponseDecoder, DatagramDnsResponseEncoder, DatagramPacketDecoder, DatagramPacketEncoder, DelimiterBasedFrameDecoder, DynamicAddressConnectHandler, FastLzFrameDecoder, FastLzFrameEncoder, FixedLengthFrameDecoder, FlowControlHandler, FlushConsolidationHandler, GlobalChannelTrafficShapingHandler, GlobalTrafficShapingHandler, HAProxyMessageDecoder, HAProxyMessageEncoder, Http2ChannelDuplexHandler, Http2ConnectionHandler, Http2FrameCodec, Http2FrameLogger, Http2MultiplexCodec, Http2MultiplexHandler, Http2StreamFrameToHttpObjectCodec, Http3ClientConnectionHandler, Http3ConnectionHandler, Http3FrameToHttpObjectCodec, Http3PushStreamClientInitializer, Http3PushStreamServerInitializer, Http3RequestStreamInboundHandler, Http3RequestStreamInitializer, Http3ServerConnectionHandler, HttpClientCodec, HttpClientUpgradeHandler, HttpContentCompressor, HttpContentDecoder, HttpContentDecompressor, HttpContentEncoder, HttpObjectAggregator, HttpObjectDecoder, HttpObjectEncoder, HttpProxyHandler, HttpRequestDecoder, HttpRequestEncoder, HttpResponseDecoder, HttpResponseEncoder, HttpServerCodec, HttpServerExpectContinueHandler, HttpServerKeepAliveHandler, HttpServerUpgradeHandler, HttpToHttp2ConnectionHandler, IdleStateHandler, InboundHttpToHttp2Adapter, IpSubnetFilter, JdkZlibDecoder, JdkZlibEncoder, JsonObjectDecoder, JZlibDecoder, JZlibEncoder, LengthFieldBasedFrameDecoder, LengthFieldPrepender, LineBasedFrameDecoder, LineEncoder, LoggingHandler, Lz4FrameDecoder, Lz4FrameEncoder, LzfDecoder, LzfEncoder, LzmaFrameEncoder, MarshallingDecoder, MarshallingEncoder, MessageAggregator, MessageToByteEncoder, MessageToMessageCodec, MessageToMessageDecoder, MessageToMessageEncoder, MqttDecoder, MqttEncoder, ObjectDecoder, ObjectEncoder, OcspClientHandler, OcspServerCertificateValidator, OptionalSslHandler, PcapWriteHandler, ProtobufDecoder, ProtobufDecoderNano, ProtobufEncoder, ProtobufEncoderNano, ProtobufVarint32FrameDecoder, ProtobufVarint32LengthFieldPrepender, ProxyHandler, QuicCodecDispatcher, ReadTimeoutHandler, RedisArrayAggregator, RedisBulkStringAggregator, RedisDecoder, RedisEncoder, ReplayingDecoder, ResolveAddressHandler, RtspDecoder, RtspEncoder, RtspObjectDecoder, RtspObjectEncoder, RtspRequestDecoder, RtspRequestEncoder, RtspResponseDecoder, RtspResponseEncoder, RuleBasedIpFilter, SctpInboundByteStreamHandler, SctpMessageCompletionHandler, SctpMessageToMessageDecoder, SctpOutboundByteStreamHandler, SimpleChannelInboundHandler, SimpleUserEventChannelHandler, SmtpRequestEncoder, SmtpResponseDecoder, SnappyFramedDecoder, SnappyFrameDecoder, SnappyFramedEncoder, SnappyFrameEncoder, SniHandler, Socks4ClientDecoder, Socks4ClientEncoder, Socks4ProxyHandler, Socks4ServerDecoder, Socks4ServerEncoder, Socks5ClientEncoder, Socks5CommandRequestDecoder, Socks5CommandResponseDecoder, Socks5InitialRequestDecoder, Socks5InitialResponseDecoder, Socks5PasswordAuthRequestDecoder, Socks5PasswordAuthResponseDecoder, Socks5PrivateAuthRequestDecoder, Socks5PrivateAuthResponseDecoder, Socks5ProxyHandler, Socks5ServerEncoder, SocksAuthRequestDecoder, SocksAuthResponseDecoder, SocksCmdRequestDecoder, SocksCmdResponseDecoder, SocksInitRequestDecoder, SocksInitResponseDecoder, SocksMessageEncoder, SocksPortUnificationServerHandler, SpdyFrameCodec, SpdyHttpCodec, SpdyHttpDecoder, SpdyHttpEncoder, SpdyHttpResponseStreamIdHandler, SpdySessionHandler, SslClientHelloHandler, SslHandler, SslMasterKeyHandler, StompSubframeAggregator, StompSubframeDecoder, StompSubframeEncoder, StringDecoder, StringEncoder, TcpDnsQueryDecoder, TcpDnsQueryEncoder, TcpDnsResponseDecoder, TcpDnsResponseEncoder, UniqueIpFilter, Utf8FrameValidator, WebSocket00FrameDecoder, WebSocket00FrameEncoder, WebSocket07FrameDecoder, WebSocket07FrameEncoder, WebSocket08FrameDecoder, WebSocket08FrameEncoder, WebSocket13FrameDecoder, WebSocket13FrameEncoder, WebSocketClientCompressionHandler, WebSocketClientExtensionHandler, WebSocketClientProtocolHandler, WebSocketExtensionDecoder, WebSocketExtensionEncoder, WebSocketFrameAggregator, WebSocketServerCompressionHandler, WebSocketServerExtensionHandler, WebSocketServerProtocolHandler, WriteTimeoutHandler, XmlDecoder, XmlFrameDecoder, ZlibDecoder, ZlibEncoder, ZstdDecoder, ZstdEncoder
ChannelPipeline.
Sub-types
ChannelHandler itself does not provide many methods, but you usually have to implement one of its subtypes:
ChannelInboundHandlerto handle inbound I/O events, andChannelOutboundHandlerto handle outbound I/O operations.
Alternatively, the following adapter classes are provided for your convenience:
ChannelInboundHandlerAdapterto handle inbound I/O events,ChannelOutboundHandlerAdapterto handle outbound I/O operations, andChannelDuplexHandlerto handle both inbound and outbound events
For more information, please refer to the documentation of each subtype.
The context object
A ChannelHandler is provided with a ChannelHandlerContext
object. A ChannelHandler is supposed to interact with the
ChannelPipeline it belongs to via a context object. Using the
context object, the ChannelHandler can pass events upstream or
downstream, modify the pipeline dynamically, or store the information
(using AttributeKeys) 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 interface Message {
// your methods here
}
public class DataServerHandler extends SimpleChannelInboundHandler<Message> {
private boolean loggedIn;
@Override
public void channelRead0(ChannelHandlerContext ctx, Message message) {
if (message instanceof LoginMessage) {
authenticate((LoginMessage) message);
loggedIn = true;
} else (message instanceof GetDataMessage) {
if (loggedIn) {
ctx.writeAndFlush(fetchSecret((GetDataMessage) message));
} else {
fail();
}
}
}
...
}
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 an unauthenticated client can get
the confidential information:
// Create a new handler instance per channel. // SeeChannelInitializer.initChannel(Channel). public class DataServerInitializer extendsChannelInitializer<Channel> {@Overridepublic void initChannel(Channelchannel) { channel.pipeline().addLast("handler", new DataServerHandler()); } }
Using AttributeKeys
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 AttributeKeys which is provided by
ChannelHandlerContext:
public interface Message {
// your methods here
}
@Sharable
public class DataServerHandler extends SimpleChannelInboundHandler<Message> {
private final AttributeKey<Boolean> auth =
AttributeKey.valueOf("auth");
@Override
public void channelRead(ChannelHandlerContext ctx, Message message) {
Attribute<Boolean> attr = ctx.attr(auth);
if (message instanceof LoginMessage) {
authenticate((LoginMessage) o);
attr.set(true);
} else (message instanceof GetDataMessage) {
if (Boolean.TRUE.equals(attr.get())) {
ctx.writeAndFlush(fetchSecret((GetDataMessage) o));
} else {
fail();
}
}
}
...
}
Now that the state of the handler is attached to the ChannelHandlerContext, you can add the
same handler instance to different pipelines:
public class DataServerInitializer extendsChannelInitializer<Channel> { private static final DataServerHandler SHARED = new DataServerHandler();@Overridepublic void initChannel(Channelchannel) { channel.pipeline().addLast("handler", SHARED); } }
The @Sharable annotation
In the example above which used an AttributeKey,
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 more ChannelPipelines 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 ChannelHandler, and
ChannelPipeline to find out more about inbound and outbound operations,
what fundamental differences they have, how they flow in a pipeline, and how to handle
the operation in your application.
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic @interfaceIndicates that the same instance of the annotatedChannelHandlercan be added to one or moreChannelPipelines multiple times without a race condition. -
Method Summary
Modifier and TypeMethodDescriptionvoidexceptionCaught(ChannelHandlerContext ctx, Throwable cause) Deprecated.voidGets called after theChannelHandlerwas added to the actual context and it's ready to handle events.voidGets called after theChannelHandlerwas removed from the actual context and it doesn't handle events anymore.
-
Method Details
-
handlerAdded
Gets called after theChannelHandlerwas added to the actual context and it's ready to handle events.- Throws:
Exception
-
handlerRemoved
Gets called after theChannelHandlerwas removed from the actual context and it doesn't handle events anymore.- Throws:
Exception
-
exceptionCaught
Deprecated.if you want to handle this event you should implementChannelInboundHandlerand implement the method there.Gets called if aThrowablewas thrown.- Throws:
Exception
-
ChannelInboundHandlerand implement the method there.