Netty ChannelHandler的exceptionCaught和channelInactive有什么区别

时间:2018-07-18 05:27:41

标签: netty

我正在学习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));
    }
}

1 个答案:

答案 0 :(得分:1)

在通道关闭时执行channelInActive方法,因此连接也关闭。

入站处理程序引发的任何异常都将“向上”传播到管道中,并调用此处理程序的exceptionCaught()方法,前提是下面的处理程序不使用它们。