netty4handler的执行顺序六

接上篇

先总结,网上都说的是inhandler是顺序进入pipeline(),顺序解析,但没有说1hanlder解析完如何传递给下一个,

outhandler是顺序进入pipeline(),逆序出来,但没有说逆序的时候如何传递给下一个outhanler

inhandler使用ctx.fireChannelRead(msg),传递给下一个inhandler,

outhandler使用ctx.write(msg,promise)传递给下一个outhandler

所有的inhandler的最后一个使用ctx.writeAndFlush(msg)触发给outhandler

所有的outhandler的出去口,使用ctx.writeAndFlush(msg)发送给客户端

例子

package com.wang.netty4Out.third;

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)
 * 每一次inhandler的super()或者ctx.firechannelread,操作触发outhandler的write()操作和下一个inhandler的channelread操作,每一次
 * inhandler的ctx.write()操作,触发outhandler的write()中的ctx.write()操作
 */
public class WangNetty4Out3Server {

    private static final Logger LOGGER = LoggerFactory.getLogger(WangNetty4Out3Server.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 WangOuthandler2());
                    sc.pipeline().addLast(new WangOuthandler3());
                    
                    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) {
        WangNetty4Out3Server server = new WangNetty4Out3Server();
        server.start(8085);
    }
}

package com.wang.netty4Out.third;

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.third;

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.fireChannelRead(NettyUtil.packageStringToByteBuf("I am handler2"));
    }
    
    @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.third;

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
        System.out.println(" WangInHandler3  channelRead");
        System.out.println("WangInHandler3  channelRead receive:"+NettyUtil.parseByteBufMsg(msg));
        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf(" I am inHandler3"));//最后一个indhandler需要ctx.write()而不能使用下面2行
    }
    
    @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);
    }
}

package com.wang.netty4Out.third;

import java.net.SocketAddress;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;

public class WangOuthandler1 extends ChannelOutboundHandlerAdapter{

    @Override
    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler1 bind localAddress:"+localAddress.toString());
        super.bind(ctx, localAddress, promise);
    }
    
    @Override
    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)throws Exception {
        System.out.println(" WangOuthandler1 connect remoteAddress:"+remoteAddress.toString()+" localAddress:"+localAddress.toString());
        super.connect(ctx, remoteAddress, localAddress, promise);
    }
    
    @Override
    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler1 ctx");
        super.disconnect(ctx, promise);
    }
    
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler1 close");
        super.close(ctx, promise);
    }
    
    @Override
    public void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler1 deregister");
        super.deregister(ctx, promise);
    }
    
    public void read(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler1 read");
        super.read(ctx);
    }
    
    @Override
    public void write(ChannelHandlerContext ctx, Object msg,
            ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler1 write");
        System.out.println("WangOuthandler1 receive " +NettyUtil.parseByteBufMsg(msg));
        System.out.println("WangOuthandler1 send WangOuthandler1");
        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf("WangOuthandler1"));
//        super.write(ctx, msg, promise);
    }
    
    public void flush(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler1 flush");
        super.flush(ctx);
    }
}

package com.wang.netty4Out.third;

import java.net.SocketAddress;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;

public class WangOuthandler2 extends ChannelOutboundHandlerAdapter{

    @Override
    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler2 bind localAddress:"+localAddress.toString());
        super.bind(ctx, localAddress, promise);
    }
    
    @Override
    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)throws Exception {
        System.out.println(" WangOuthandler2 connect remoteAddress:"+remoteAddress.toString()+" localAddress:"+localAddress.toString());
        super.connect(ctx, remoteAddress, localAddress, promise);
    }
    
    @Override
    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler2 ctx");
        super.disconnect(ctx, promise);
    }
    
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler2 close");
        super.close(ctx, promise);
    }
    
    @Override
    public void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler2 deregister");
        super.deregister(ctx, promise);
    }
    
    public void read(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler2 read");
        super.read(ctx);
    }
    
    @Override
    public void write(ChannelHandlerContext ctx, Object msg,
            ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler2 write");
        System.out.println("WangOuthandler2 receive " +NettyUtil.parseByteBufMsg(msg));
//        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf("WangOuthandler2"));
        System.out.println("WangOuthandler2 send WangOuthandler2");
        ctx.write(NettyUtil.packageStringToByteBuf("WangOuthandler2"), promise);
//        super.write(ctx, msg, promise);
    }
    
    public void flush(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler2 flush");
        super.flush(ctx);
    }
}

package com.wang.netty4Out.third;

import java.net.SocketAddress;

import com.wang.netty4.six.NettyUtil;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;

public class WangOuthandler3 extends ChannelOutboundHandlerAdapter{

    @Override
    public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler3 bind localAddress:"+localAddress.toString());
        super.bind(ctx, localAddress, promise);
    }
    
    @Override
    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress,SocketAddress localAddress, ChannelPromise promise)throws Exception {
        System.out.println(" WangOuthandler3 connect remoteAddress:"+remoteAddress.toString()+" localAddress:"+localAddress.toString());
        super.connect(ctx, remoteAddress, localAddress, promise);
    }
    
    @Override
    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler3 ctx");
        super.disconnect(ctx, promise);
    }
    
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler3 close");
        super.close(ctx, promise);
    }
    
    @Override
    public void deregister(ChannelHandlerContext ctx, ChannelPromise promise)
            throws Exception {
        System.out.println(" WangOuthandler3 deregister");
        super.deregister(ctx, promise);
    }
    
    public void read(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler3 read");
        super.read(ctx);
    }
    
    @Override
    public void write(ChannelHandlerContext ctx, Object msg,
            ChannelPromise promise) throws Exception {
        System.out.println(" WangOuthandler3 write");
        System.out.println("WangOuthandler3 receive " +NettyUtil.parseByteBufMsg(msg));
        System.out.println("WangOuthandler3 send WangOuthandler3");
//        ctx.writeAndFlush(NettyUtil.packageStringToByteBuf("WangOuthandler3"));
        ctx.write(NettyUtil.packageStringToByteBuf("WangOuthandler3"), promise);
//        super.write(ctx, msg, promise);
    }
    
    public void flush(ChannelHandlerContext ctx) throws Exception {
        System.out.println(" WangOuthandler3 flush");
        super.flush(ctx);
    }
}

服务端运行结果

 WangInHandler1  channelRegistered
 WangInHandler2  channelRegistered
 WangInHandler3  channelRegistered
 WangInHandler1  channelActive
 WangInHandler2  channelActive
 WangInHandler3  channelActive
 WangOuthandler3 read
 WangOuthandler2 read
 WangOuthandler1 read
 WangInHandler1  channelRead
 WangInHandler1 receive:Are you ok?
 WangInHandler2  channelRead
 WangInHandler2 receive:
 WangInHandler3  channelRead
WangInHandler3  channelRead receive:I am handler2
 WangOuthandler3 write
WangOuthandler3 receive  I am inHandler3
WangOuthandler3 send WangOuthandler3
 WangOuthandler2 write
WangOuthandler2 receive WangOuthandler3
WangOuthandler2 send WangOuthandler2
 WangOuthandler1 write
WangOuthandler1 receive WangOuthandler2
WangOuthandler1 send WangOuthandler1
 WangOuthandler3 flush
 WangOuthandler2 flush
 WangOuthandler1 flush
 WangInHandler1  channelReadComplete
 WangInHandler2  channelReadComplete
 WangInHandler3  channelReadComplete
 WangOuthandler3 read
 WangOuthandler2 read
 WangOuthandler1 read

客户断运行结果

channelActive
ctx.channel().localAddress():/192.168.1.31:58971
channelRead
Server said:WangOuthandler1

可以看到和我们预想的一样,客户端只收到一次返回,而服务断通过

WangInHandler1  channelRead

 WangInHandler2  channelRead

WangInHandler3  channelRead

WangOuthandler3 write

WangOuthandler2 write

WangOuthandler1 write

的方式进行数据解析、发送

猜你喜欢

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