Netty|03 Handler运行顺序

测试handler的运行过程

1、测试用例包括两个InboundHandler与OuuboundHandler
2、所有的导包都没有在代码中,需要自行添加

1、Demo搭建

2、编写NettyServer

public class NettyServer {    public static void main(String[] args) throws InterruptedException {//        创建线程池 接受连接        NioEventLoopGroup bossGroup = new NioEventLoopGroup();//        创建线程池,处理io        NioEventLoopGroup workGroup = new NioEventLoopGroup();//        创建服务器端启动助手        ServerBootstrap serverBootstrap = new ServerBootstrap();//        配置启动助手        serverBootstrap.group(bossGroup, workGroup)//设置两个线程池                .channel(NioServerSocketChannel.class)//使用作为服务器端的通道实现                .option(ChannelOption.SO_BACKLOG, 128)//设置线程队列中等待连接的个数                .childOption(ChannelOption.SO_KEEPALIVE, true)//保持活动连接状态                .childHandler(new ChannelInitializer<SocketChannel>() { //创建通道初始化的对象                    @Override                    protected void initChannel(SocketChannel ch) throws Exception {                        ChannelPipeline pipeline = ch.pipeline();                        pipeline.addLast("decoder",new StringDecoder());                        pipeline.addLast("encoder",new StringEncoder());                        pipeline.addLast(new NettyServerOutHandler());                        pipeline.addLast(new NettyServerOutHandler2());                        pipeline.addLast(new NettyServerInHandler());                        pipeline.addLast(new NettyServerInHandler2());                    }                });        System.out.println("----------------server is ready--------------------");        ChannelFuture cf = serverBootstrap.bind(9999).sync();//绑定端口,异步        System.out.println("----------------server is starting--------------------");//        关闭通道、关闭通道组        cf.channel().closeFuture().sync();        bossGroup.shutdownGracefully();        workGroup.shutdownGracefully();
    }}

3、编写NettyServerInHandler和NettyServerInHandler2

public class NettyServerInHandler extends ChannelInboundHandlerAdapter {
    @Override    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelRegistered");    }
    @Override    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelUnregistered");    }
    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelActive");    }
    @Override    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelInactive");    }
    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelReadComplete");        ctx.channel().writeAndFlush("服务器发送0-0");    }
    @Override    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {        System.out.println("NettyServerInHandler userEventTriggered");    }
    @Override    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler channelWritabilityChanged");    }
    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        System.out.println("NettyServerInHandler exceptionCaught");    }
    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("NettyServerInHandler channelRead接收到客户端的数据:"+(String)msg);//        事件传播        ctx.fireChannelRead(msg);    }}
public class NettyServerInHandler2 extends ChannelInboundHandlerAdapter {
    @Override    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelRegistered");    }
    @Override    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelUnregistered");    }
    @Override    public void channelActive(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelActive");    }
    @Override    public void channelInactive(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelInactive");    }
    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelReadComplete");        ctx.channel().writeAndFlush("服务器发送0-0");    }
    @Override    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {        System.out.println("NettyServerInHandler2 userEventTriggered");    }
    @Override    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {        System.out.println("NettyServerInHandler2 channelWritabilityChanged");    }
    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        System.out.println("NettyServerInHandler2 exceptionCaught");    }
    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        System.out.println("NettyServerInHandler2 channelRead接收到客户端的数据:"+(String)msg);    }}

4、编写NettyServerOutHandler与NettyServerOutHandler2

public class NettyServerOutHandler extends ChannelOutboundHandlerAdapter {    /**     * 写数据     * @param ctx     * @param msg     * @param promise     * @throws Exception     */    @Override    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {        System.out.println("ServerOutHandler:"+(String) msg);        ctx.write(msg,promise);    }}
public class NettyServerOutHandler2 extends ChannelOutboundHandlerAdapter {    /**     * 写数据     * @param ctx     * @param msg     * @param promise     * @throws Exception     */    @Override    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {        System.out.println("ServerOutHandler2:"+(String) msg);        ctx.write(msg,promise);    }}

5、编写NettyClient

public class NettyClient {    public static void main(String[] args) throws InterruptedException {//        创建一个线程组        NioEventLoopGroup group = new NioEventLoopGroup();        //2. 创建客户端的启动助手,完成相关配置        Bootstrap bootstrap = new Bootstrap();        bootstrap.group(group)//3. 设置线程组                .channel(NioSocketChannel.class)//4. 设置客户端通道的实现类                .handler(new ChannelInitializer<SocketChannel>() {//5. 创建一个通道初始化对象                    @Override                    protected void initChannel(SocketChannel ch) throws Exception {                        ChannelPipeline pipeline = ch.pipeline();                        pipeline.addLast("encoder",new StringEncoder());                        pipeline.addLast("decoder",new StringDecoder());                        pipeline.addLast(new NettyClientHandler());//6.往Pipeline链中添加自定义的handler                    }                });        System.out.println("......Client is  ready......");
        //7.启动客户端去连接服务器端  connect方法是异步的   sync方法是同步阻塞的        ChannelFuture cf = bootstrap.connect("127.0.0.1", 9999).sync();//        发送消息        cf.channel().writeAndFlush("哈哈哈");//        关闭连接        cf.channel().closeFuture().sync();
    }}

6、编写NettyClientHandler

public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
    /**     * 读数据     * @param ctx     * @param msg     * @throws Exception     */    @Override    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {        System.out.println("服务器发来消息:"+msg);    }}

7、运行结果

服务器端:
----------------server is ready--------------------
----------------server is starting--------------------
NettyServerInHandler channelRegistered
NettyServerInHandler channelActive
NettyServerInHandler channelRead接收到客户端的数据:哈哈哈
NettyServerInHandler2 channelRead接收到客户端的数据:哈哈哈
NettyServerInHandler channelReadComplete
ServerOutHandler2:服务器发送0-0
ServerOutHandler:服务器发送0-0

客户端:
......Client is ready......
服务器发来消息:服务器发送0-0

强制关闭客户端:
NettyServerInHandler channelReadComplete
ServerOutHandler2:服务器发送0-0
ServerOutHandler:服务器发送0-0
NettyServerInHandler exceptionCaught
NettyServerInHandler userEventTriggered
NettyServerInHandler channelInactive
NettyServerInHandler channelUnregistered

8、分析结果

由此可以看出,inboundHandler的执行顺序是:
channelRegistered→channelActive→channelRead→传播到第二个inboundhandler的channelRead
→channelReadComplete→往上一个ServerOutHandler2→再往上ServerOutHandler传播,最后发送到客户端NettyClientInHandler的channelRead中接收到数据。

异常出现的执行顺序:
channelReadComplete→exceptionCaught→userEventTriggered→channelInactive→channelUnregistered。

分析得出:
1、通道先注册再会处于活跃状态
2、通道read结束后才会触发readComplete
3、当inboundHandler中触发一个write方法,就会往该链上的上一个outboundHandler中触发write方法,然后再往上触发,直到没有outboundHandler为止,就会发送消息到客户端。
4、通道关闭会再次触发readComplete,然后触发异常方法exceptionCaught,接下来触发userEventTriggered,最后触发channelInactive与channelUnregistered。
5、readComplete方法是在所有的inboundHandler跑完之后才触发的方法,并且只会触发第一个inboundHandler的readComplete方法。

重磅推荐

想要进群一起学习的小伙伴,快来加小刀微信啦  

微信号:best396975802

END

小哥哥小姐姐,

点个在看再走吧~(づ ̄3 ̄)づ╭❤~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值