ChannelPipeline.
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.
ChannelHandler 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 messageReceived(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 a 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()); } }
AttributeKeysAttributeKeys which is provided by
ChannelHandlerContext:
public interface Message {
// your methods here
}
public class DataServerHandler extends SimpleChannelInboundHandler<Message> {
private final AttributeKey<Boolean> auth =
AttributeKey.valueOf("auth") ;
@Override
public boolean isSharable() {
return true;
}
@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); } }
isSharable() method
In the example above which used an AttributeKey,
you might have noticed the isSharable() method is override to return true.
If the ChannelHandler#isSharable() is returningtrue,
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 method is not implemented and return false, 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.
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.
| Modifier and Type | Method and Description |
|---|---|
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx, SocketAddress ChannelHandlerContext for which the bind operation is madethe localAddress)SocketAddress to which it should boundCalled once a bind operation is made. |
| public default void | |
| public default void | channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause)
Gets called if a |
| public default void | channelInactive(ChannelHandlerContext ctx)
The |
| public default void | channelInboundEvent(ChannelHandlerContext ctx, Object evt)
Gets called if a custom inbound event happened. |
| public default void | channelRead(ChannelHandlerContext ctx, Object msg)
Invoked when the current |
| public default void | channelReadComplete(ChannelHandlerContext ctx)
Invoked when the last message read by the current read operation has been consumed by
|
| public default void | channelRegistered(ChannelHandlerContext ctx)
The |
| public default void | channelShutdown(ChannelHandlerContext
the ctx, ChannelShutdownDirection ChannelHandlerContext for which we notify about the completed shutdown.the direction)ChannelShutdownDirection of the completed shutdown.The |
| public default void | channelUnregistered(ChannelHandlerContext ctx)
The |
| public default void | channelWritabilityChanged(ChannelHandlerContext ctx)
Gets called once the writable state of a |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx)ChannelHandlerContext for which the close operation is madeCalled once a close operation is made. |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx, SocketAddress ChannelHandlerContext for which the connect operation is madethe remoteAddress, SocketAddress SocketAddress to which it should connectthe localAddress)SocketAddress which is used as source on connectCalled once a connect operation is made. |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx)ChannelHandlerContext for which the deregister operation is madeCalled once a deregister operation is made from the current registered |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx)ChannelHandlerContext for which the disconnect operation is madeCalled once a disconnect operation is made. |
| public default void | flush(ChannelHandlerContext
the ctx)ChannelHandlerContext for which the flush operation is madeCalled once a flush operation is made. |
| public default void | handlerAdded(ChannelHandlerContext ctx)
Gets called after the |
| public default void | handlerRemoved(ChannelHandlerContext ctx)
Gets called after the |
| public default boolean | isSharable()
Returns |
| public default long | Returns: the number of buffered / queued bytes.the ctx)ChannelHandlerContext for which the operation is made.The number of the outbound bytes that are buffered / queued in this |
| public default void | read(ChannelHandlerContext
the ctx, ReadBufferAllocator ChannelHandlerContext for which the read operation is madeThe readBufferAllocator)ReadBufferAllocator that should be used to allocate a Buffer
if needed (for reading the data).Called once a read operation is made from the current registered |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx)ChannelHandlerContext for which the register operation is madeCalled once a register operation is made to register for IO on the |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx, Object ChannelHandlerContext for which the operation is made.the event. event)Called once a custom defined outbound event was sent. |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx, ChannelShutdownDirection ChannelHandlerContext for which the shutdown operation is madethe direction)ChannelShutdownDirection that is used.Called once a shutdown operation was requested and should be executed. |
| public default Future | Returns: theFuture which will be notified once the operation completes.the ctx, Object ChannelHandlerContext for which the write operation is madethe message to write msg)Called once a write operation is made. |
| bind | back to summary |
|---|---|
| public default Future Called once a bind operation is made.
| |
| channelActive | back to summary |
|---|---|
| public default void channelActive(ChannelHandlerContext ctx) throws Exception The
| |
| channelExceptionCaught | back to summary |
|---|---|
| public default void channelExceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception Gets called if a
| |
| channelInactive | back to summary |
|---|---|
| public default void channelInactive(ChannelHandlerContext ctx) throws Exception The
| |
| channelInboundEvent | back to summary |
|---|---|
| public default void channelInboundEvent(ChannelHandlerContext ctx, Object evt) throws Exception Gets called if a custom inbound event happened.
| |
| channelRead | back to summary |
|---|---|
| public default void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception Invoked when the current
| |
| channelReadComplete | back to summary |
|---|---|
| public default void channelReadComplete(ChannelHandlerContext ctx) throws Exception Invoked when the last message read by the current read operation has been consumed by
| |
| channelRegistered | back to summary |
|---|---|
| public default void channelRegistered(ChannelHandlerContext ctx) throws Exception The
| |
| channelShutdown | back to summary |
|---|---|
| public default void channelShutdown(ChannelHandlerContext ctx, ChannelShutdownDirection direction) throws Exception The
| |
| channelUnregistered | back to summary |
|---|---|
| public default void channelUnregistered(ChannelHandlerContext ctx) throws Exception The
| |
| channelWritabilityChanged | back to summary |
|---|---|
| public default void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception Gets called once the writable state of a
| |
| close | back to summary |
|---|---|
| public default Future Called once a close operation is made.
| |
| connect | back to summary |
|---|---|
| public default Future Called once a connect operation is made.
| |
| deregister | back to summary |
|---|---|
| public default Future Called once a deregister operation is made from the current registered
| |
| disconnect | back to summary |
|---|---|
| public default Future Called once a disconnect operation is made.
| |
| flush | back to summary |
|---|---|
| public default void flush(ChannelHandlerContext ctx) Called once a flush operation is made. The flush operation will try to flush out all previous written messages that are pending.
| |
| handlerAdded | back to summary |
|---|---|
| public default void handlerAdded(ChannelHandlerContext ctx) throws Exception Gets called after the | |
| handlerRemoved | back to summary |
|---|---|
| public default void handlerRemoved(ChannelHandlerContext ctx) throws Exception Gets called after the | |
| isSharable | back to summary |
|---|---|
| public default boolean isSharable() Returns | |
| pendingOutboundBytes | back to summary |
|---|---|
| public default long pendingOutboundBytes(ChannelHandlerContext ctx) The number of the outbound bytes that are buffered / queued in this
| |
| read | back to summary |
|---|---|
| public default void read(ChannelHandlerContext ctx, ReadBufferAllocator readBufferAllocator) Called once a read operation is made from the current registered
| |
| register | back to summary |
|---|---|
| public default Future Called once a register operation is made to register for IO on the
| |
| sendOutboundEvent | back to summary |
|---|---|
| public default Future Called once a custom defined outbound event was sent. This operation will pass the event through the
| |
| shutdown | back to summary |
|---|---|
| public default Future Called once a shutdown operation was requested and should be executed.
| |
| write | back to summary |
|---|---|
| public default Future Called once a write operation is made. The write operation will write the messages through the
| |