netty4handler的执行顺序四

接上篇,本例中加有outhandler,先说明,本例是个不正常程序,只能用于理解

1)outhandler要放到inhandler之前,或者至少一个inhandler之前,否者outhadler.write不运行

package com.wang.netty4Out.first;

import org.apache.cassandra.cli.CliParser.newColumnFamily_return;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * 这个用于测试handler的传递功能
 * @author wangzg
 *
 * 本例子使用的是 实现的handler中,各个函数都是先super,然后打印,除了handler1中的channelRead,这样打印出的顺序是,先2后1,也就是最后加进去的,先做,先进去的后做,跟
 * 网上的不一致
 *
 * 本例子中各个handler中的方法,都在最后使用了super()的方法,顺序和网上的一致
 *
 * 本例子将用于数据解析
 * 本例的例子是inhandler2 和inhandler3都发送了数据,但是客户断接收的时候,是连在一起的,因此这里需要想办法,也就是连包拆包
 *
 * 本例子发现个问题,在Inhandler中都可以使用ctx.writeAndflush(msg),但这样的做法会造成,如果有outhandler的时候,发送回客户端的数据,有多个
 * outhandler发回的数据(都是一样的,个数是inhander中ctx.writeAndFlush()个数),如何解决的,既然需要msg向后传递,又不能
 * 有多个重复数据发回,那就需要在inhandler的channelRead()不能使用super.channelread(),而是使用ctx.fireChannelRead(加工过的msg)
 */
public class WangNetty4Out1Server {

    private static final Logger LOGGER = LoggerFactory.getLogger(WangNetty4Out1Server.class);
    
    public void start(int port){
        EventLoopGroup boss = new NioEventLoopGroup();
        EventLoopGroup work = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.group(boss, work)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 1024)
//            .option(ChannelOption.SO_TIMEOUT, 5 * 1000)
            .childOption(ChannelOption.SO_KEEPALIVE, true)
            .childOption(ChannelOption.SO_RCVBUF, 10 * 1024)
            .childOption(ChannelOption.SO_SNDBUF, 10 * 1024)
            .childHandler(new ChannelInitializer<SocketChannel>() {

                @Override
                protected void initChannel(SocketChannel sc) throws Exception {
                    sc.pipeline().addLast(new WangOuthandler1());
                    
                    sc.pipeline().addLast(new WangInHandler1());
                    sc.pipeline().addLast(new WangInHandler2());
                    sc.pipeline().addLast(new WangInHandler3());
                    
//                    sc.pipeline().addLast(new WangOuthandler1());
                    
                }
            });
            ChannelFuture future = bootstrap.bind(port).sync();
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            LOGGER.error("server 启动失败",e);
        }finally{
            boss.shutdownGracefully();
            work.shutdownGracefully();
        }
    }
    
    public static void main(String[] args) {
        WangNetty4Out1Server server = new WangNetty4Out1Server();
        server.start(8085);
    }
}

package com.wang.netty4Out.first;

import org.apache.cassandra.utils.OutputHandler.SystemOutput;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class WangInHandler1 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelRead");
        System.out.println(" WangInHandler1 receive:"+NettyUtil.parseByteBufMsg(msg));
        ctx.fireChannelRead(msg);
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelReadComplete");
        super.channelReadComplete(ctx);
        
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  exceptionCaught");
        super.exceptionCaught(ctx, cause);
        
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelActive");
        super.channelActive(ctx);
        
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelInactive");
        super.channelInactive(ctx);
        
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelRegistered");
        super.channelRegistered(ctx);
        
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelUnregistered");
        super.channelUnregistered(ctx);
        
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  channelWritabilityChanged");
        super.channelWritabilityChanged(ctx);
        
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler1  userEventTriggered");
        super.userEventTriggered(ctx, evt);
        
    }
}

package com.wang.netty4Out.first;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class WangInHandler2 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelRead");
        System.out.println(" WangInHandler2 receive:"+NettyUtil.parseByteBufMsg(msg));
        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf("I am handler2"));
//        ctx.write(NettyUtil.packageStringToByteBuf(" I am inhandler2"));
        super.channelRead(ctx, msg);
//        ctx.fireChannelRead(NettyUtil.packageStringToByteBuf("aaaaaaa"));
        
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelReadComplete");
        super.channelReadComplete(ctx);
        
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  exceptionCaught");
        super.exceptionCaught(ctx, cause);
        
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelActive");
        super.channelActive(ctx);
        
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelInactive");
        super.channelInactive(ctx);
        
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelRegistered");
        super.channelRegistered(ctx);
        
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelUnregistered");
        super.channelUnregistered(ctx);
        
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  channelWritabilityChanged");
        super.channelWritabilityChanged(ctx);
        
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler2  userEventTriggered");
        super.userEventTriggered(ctx, evt);
        
    }
}

package com.wang.netty4Out.first;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class WangInHandler3 extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // TODO Auto-generated method stub
//        super.channelRead(ctx, msg);
        System.out.println(" WangInHandler3  channelRead");
        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf(" I am inHandler3"));
//        ctx.writeAndFlush(msg);
    }
    
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelReadComplete");
        super.channelReadComplete(ctx);
        
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  exceptionCaught");
        super.exceptionCaught(ctx, cause);
        
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelActive");
        super.channelActive(ctx);
        
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelInactive");
        super.channelInactive(ctx);
        
    }
    
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelRegistered");
        super.channelRegistered(ctx);
        
    }
    
    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelUnregistered");
        super.channelUnregistered(ctx);
        
    }
    
    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  channelWritabilityChanged");
        super.channelWritabilityChanged(ctx);
        
    }
    
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        // TODO Auto-generated method stub
        System.out.println(" WangInHandler3  userEventTriggered");
        super.userEventTriggered(ctx, evt);
    }
}

运行结果

服务端

 WangInHandler1  channelRegistered
 WangInHandler2  channelRegistered
 WangInHandler3  channelRegistered
 WangInHandler1  channelActive
 WangInHandler2  channelActive
 WangInHandler3  channelActive
 WangOuthandler1 read
 WangInHandler1  channelRead
 WangInHandler1 receive:Are you ok?

 WangInHandler2  channelRead
 WangInHandler2 receive:
 WangOuthandler1 write
WangOuthandler1 receive I am handler2
 WangOuthandler1 flush
 WangInHandler3  channelRead
 WangOuthandler1 write
WangOuthandler1 receive  I am inHandler3
 WangOuthandler1 flush

 WangInHandler1  channelReadComplete
 WangInHandler2  channelReadComplete
 WangInHandler3  channelReadComplete
 WangOuthandler1 read

客户断

channelActive
ctx.channel().localAddress():/192.168.1.31:58072
channelRead

Server said:WangOuthandler1WangOuthandler1

大家可以看到我的客户端接收到了2个WangOuthandler1,原因是Inhandler2和inhandler3都ctx.writeandflush()的原因,同时还有indhandler2的super.channelRead(ctx, msg);

在看服务端,由于我的outhandler放在了inhandler之前,因此WangOuthandler1 read WangInHandler1  channelRead

同时因为inhandler2的super原因,outhandler1.write第一次接收到了数据,进行写操作,发送给客户端,inhandler3的writeandflush(),再次进入outhandler.write()操作,发送给客户端,因此客户端收到了2个数据WangOuthandler1,因此当inhandler中每一次ctx.write()或这ctx.writeandflush,outhandler1都会发送给客户端,只有使用ctx.firechannelread,不会触发outhandler操作



猜你喜欢

转载自blog.csdn.net/fivestar2009/article/details/80521958