Netty之ChannelHandler
ChannelHandler
Handles an I/O event or intercepts an I/O operation, and forwards it to its next handler in its ChannelPipeline.
处理I/O事件或截取I/O操作,并将其转发到ChannelPipeline中的下一个Handler。
使用netty实现自我业务的扩展点。一般使用ChannelHandler的子类型ChannelInboundHandler和ChannelOutboundHandler。
但由于不想重写所有的接口方法,可以使用它们的Adapter。
ChannelHandler
public interface ChannelHandler {
// Gets called after the ChannelHandler was added to the actual context and it's ready to handle events.
// 当前Handler加入ChannelHandlerContext时的回调
void handlerAdded(ChannelHandlerContext ctx) throws Exception;
// Gets called after the ChannelHandler was removed from the actual context and it doesn't handle events anymore.
// 当前Handler从ChannelHandlerContext移除时的回调
void handlerRemoved(ChannelHandlerContext ctx) throws Exception;
// 发生异常时的回调
// Gets called if a Throwable was thrown.
// if you want to handle this event you should implement ChannelInboundHandler and implement the method there.
@Deprecated
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
@Inherited
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Sharable {
// no value
}
}
ChannelInboundHandler
/**
* 能够为状态变化添加回调的ChannelHandler. 在状态更改时,它使用户可以轻松的挂载钩子。
* {@link ChannelHandler} which adds callbacks for state changes. This allows the user
* to hook in to state changes easily.
*/
public interface ChannelInboundHandler extends ChannelHandler {
/**
* 触发时机:当前Channel注册到EventLoop
* The {@link Channel} of the {@link ChannelHandlerContext} was registered with its {@link EventLoop}
*/
void channelRegistered(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:当前Chanel从EventLoop中取消注册
* The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop}
*/
void channelUnregistered(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:当前Channel活跃的时候
* The {@link Channel} of the {@link ChannelHandlerContext} is now active
*/
void channelActive(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:当前Channel不活跃的时候,即Channel到了它的生命周期末
* The {@link Channel} of the {@link ChannelHandlerContext} was registered is now inactive and reached its
* end of lifetime.
*/
void channelInactive(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:当前Channel从远程读到数据
* Invoked when the current {@link Channel} has read a message from the peer.
*/
void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception;
/**
* 触发时机:channelRead消费完读取的数据
* Invoked when the last message read by the current read operation has been consumed by
* {@link #channelRead(ChannelHandlerContext, Object)}. If {@link ChannelOption#AUTO_READ} is off, no further
* attempt to read an inbound data from the current {@link Channel} will be made until
* {@link ChannelHandlerContext#read()} is called.
*/
void channelReadComplete(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:用户事件触发时
* Gets called if an user event was triggered.
*/
void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
/**
* 触发时机:Chanel的写状态变化的时候触发
* Gets called once the writable state of a {@link Channel} changed. You can check the state with
* {@link Channel#isWritable()}.
*/
void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception;
/**
* Gets called if a {@link Throwable} was thrown.
*/
@Override
@SuppressWarnings("deprecation")
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
}
ChannelOutboundHandler
/**
* 收到IO出站操作通知的ChannelHandler
* {@link ChannelHandler} which will get notified for IO-outbound-operations.
*
* 注意:有些方法有ChannelPromise参数,可以使用promise.addListener()注册监听,当回调方法执行完成后会触发监听
*/
public interface ChannelOutboundHandler extends ChannelHandler {
/**
* 触发时机:bind操作执行前
* Called once a bind operation is made.
*
* @param ctx the {@link ChannelHandlerContext} for which the bind operation is made
* @param localAddress the {@link SocketAddress} to which it should bound
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void bind(ChannelHandlerContext ctx, SocketAddress localAddress, ChannelPromise promise) throws Exception;
/**
* 触发时机:connect操作执行前
* Called once a connect operation is made.
*
* @param ctx the {@link ChannelHandlerContext} for which the connect operation is made
* @param remoteAddress the {@link SocketAddress} to which it should connect
* @param localAddress the {@link SocketAddress} which is used as source on connect
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void connect(
ChannelHandlerContext ctx, SocketAddress remoteAddress,
SocketAddress localAddress, ChannelPromise promise) throws Exception;
/**
* 触发时机:disconnect操作执行前
* Called once a disconnect operation is made.
*
* @param ctx the {@link ChannelHandlerContext} for which the disconnect operation is made
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
/**
* 触发时机:close操作执行前
* Called once a close operation is made.
*
* @param ctx the {@link ChannelHandlerContext} for which the close operation is made
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
/**
* 触发时机:deregister操作执行前
* Called once a deregister operation is made from the current registered {@link EventLoop}.
*
* @param ctx the {@link ChannelHandlerContext} for which the close operation is made
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
/**
* 触发时机:read操作执行前
* Intercepts {@link ChannelHandlerContext#read()}.
*/
void read(ChannelHandlerContext ctx) throws Exception;
/**
* 触发时机:write操作执行前
* Called once a write operation is made. The write operation will write the messages through the
* {@link ChannelPipeline}. Those are then ready to be flushed to the actual {@link Channel} once
* {@link Channel#flush()} is called
*
* @param ctx the {@link ChannelHandlerContext} for which the write operation is made
* @param msg the message to write
* @param promise the {@link ChannelPromise} to notify once the operation completes
* @throws Exception thrown if an error occurs
*/
void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception;
/**
* 触发时机:flush操作执行前
* Called once a flush operation is made. The flush operation will try to flush out all previous written messages
* that are pending.
*
* @param ctx the {@link ChannelHandlerContext} for which the flush operation is made
* @throws Exception thrown if an error occurs
*/
void flush(ChannelHandlerContext ctx) throws Exception;
}
DEMO
public void clientMode() throws Exception {
NioEventLoopGroup thread = new NioEventLoopGroup(1);
}
参考文章:
https://juejin.cn/post/6844903597302349831
https://netty.io/4.1/api/io/netty/channel/ChannelHandler.html
保持微笑,时刻冷静,相信自己也相信队友,坚持信念