我正在学习Netty,并且对ChannelHandler的channelInactive和exceptionCaught感到困惑。
据我了解,当服务器关闭时,客户端将收到IOEException,但是如果服务器明确关闭通道,则客户端将获得WRITE_IDEL事件,并且可以自行定义后处理。
但是从演示波纹管中,我得到了不同的结果。我关闭了服务器,客户端跳到channelInactive方法,但没有exceptionCaught。
ClientHandler:
package echoclient;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
/**
* Created by lulijun on 2018/2/12.
*/
@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("channel active");
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel inactive");
}
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
System.out.println("Client received: "+in.toString(CharsetUtil.UTF_8));
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleState state= ((IdleStateEvent) evt).state();
if (state == IdleState.WRITER_IDLE) {
// read timeout, break the channel
System.out.println("client write timeout");
SocketAddress remoteAddress = ctx.channel().remoteAddress();
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
System.out.println("channel exception");
cause.printStackTrace();
if (cause instanceof IOException) {
SocketAddress remoteAddress = ctx.channel().remoteAddress();
// reconnect
ctx.channel().close();
ctx.connect(remoteAddress);
} else {
ctx.channel().close();
}
}
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("Client received: "+msg.toString(CharsetUtil.UTF_8));
}
}
答案 0 :(得分:1)
在通道关闭时执行channelInActive方法,因此连接也关闭。
入站处理程序引发的任何异常都将“向上”传播到管道中,并调用此处理程序的exceptionCaught()方法,前提是下面的处理程序不使用它们。