4.1 Channelhandler
4.1.1 Channel声明周期(状态事件)
方法 | 描述 |
---|---|
ChannelUnregistered | Channnel已创建,但是未注册到EventLoop |
ChannelRegistered | Channnel已注册到EventLoop |
ChannelActive | Channnel活动状态(已连接到远程节点),可以发送接收数据 |
ChannelInactive | Channnel未连接到远程站点 |
4.1.2 Channelhandler生命周期(状态事件)
从channelPipeLine中添加删除时触发
方法 | 描述 |
---|---|
handlerAdded | 当把handler添加到channelPipieLine中时 |
handlerRemoved | 从pipeLine中移除时 |
exceptionCaught | handler处理过程中异常时调用 |
4.1.3 ChannelInBoundHandler接口--入站数据及状态变化
ChannelInBoundHandlerAdapter--调用read后如果不继续调用ctx.fireChannelRead(msg)将消息传给下一个channel(即丢弃消息),则需要手动释放(ReferenceCountutil.release(msg))
SimpleChannelInBoundHandler -- 已封装,自动释放资源
方法 | 描述 |
---|---|
channelRead | 从channel中读取数据时 |
channelReadComplete | 所有数据都已从Channel中读取之后调用(可能之前channelRead已多次调用) |
userEventTriggered | 当ChannelInBoundHandler.fireuserEventTriggered()被调用时触发 |
4.1.3 ChannelOutBoundHandler 接口--出站数据及拦截操作
a). 可按需推迟操作或者事件.
b). 方法被channel、channelPipeLine及channelHandlerContext调用
方法 | 描述 |
---|---|
bind | |
connect | |
disconnect | |
close | |
deregister | |
read(ChannelhandlerContext) | 当请求从channel读取数据时调用 |
flush | 写数据到远端 |
write | write后不传递消息时需要手动释放,ReferenceCountutil.release(msg);promise.setSuccess(); |
4.2 ChannelPipeLine-channelhandler实例链
a). 可动态修改
b). fireChannelread之类方法都是调用ChannelPipeLine中下一个handler中对应方法.
方法 | 描述 |
---|---|
addFist | |
addBefore | |
addAfter | |
addlast | |
remove | |
replace | 以上都是处理内部channelHandler的方法 |
4.3 ChannelHandlerContext接口-handler和pipeLine之间的连接
4.4 异常处理
4.4.1 入站异常
a). 异常从出发的那一点开始流经pipiLine
b). exceptionCaught默认实现是将异常转发下一个handler处理
c). 如果到达尾部还未处理则被记录为未处理
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf>{
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
cause.printStackTrace();
ctx.close();
}
}
4.4.2 出站异常
a). 每个出站操作都返回一个ChannelFuture
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise){
promise.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if( !future.isSuccess() ){
future.cause().printStackTrace();
future.channel().close();
}
}
})
}