Netty入门P10

pipline与channelHandler

在服务端或者客户端收到数据之后的处理流程大致分为以下几步:
pipline与channelHandler
在Netty中pipline和ChannelHandler通过责任链设计模式来组织代码逻辑,并且能够支持逻辑的动态添加和删除,Netty能够支持各类协议的扩展。

pipline与channelHandler的构成

基本构成示意图:
pipline与channelHandler2
无论在客户端还是服务端,一条连接对应着一个Channel,每一个Channel所有的处理逻辑都在一个叫做ChannelPipline的对象里边,ChannelPipline是一个双向链表,ChannelPiplin与Channel是一一对应的。

ChannelPipeline每一个节点都是ChannelHandlerContext对象,ChannelHandlerContext能够获取到Channel相关的所有上下文信息,ChannelHandlerContext又包含了一个ChannelHandler。

ChannelHandler的分类

ChannelHandler主要有以下两个子接口:

子接口子接口说明子接口实现类
ChannelInboundHandler处理读数据的逻辑ChannelInboundHandlerAdapter
ChannelOutboundHandler处理写数据的逻辑ChannelOutboundHandlerAdapter

ChannelInboundHandler的事件传播

Server端示例代码;

/**
 * @program: learnnetty
 * @description: 事件传播
 * @create: 2020-05-08 16:40
 **/
public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel
                                .pipeline()
                                .addLast(new InboundHandlerA())
                                .addLast(new InboundHandlerB())
                                .addLast(new InboundHandlerC());
                    }
                });

        bootstrap.bind("127.0.0.1", 8080);
    }
}

处理器A示例代码:

/**
 * @program: learnnetty
 * @description: 处理器A
 * @create: 2020-05-08 16:41
 **/
public class InboundHandlerA extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("InboundHandlerA:" + msg);
        super.channelRead(ctx, msg);
    }
}

处理器B示例代码:

/**
 * @program: learnnetty
 * @description: 处理器B
 * @create: 2020-05-08 16:42
 **/
public class InboundHandlerB extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("InboundHandlerB:" + msg);
        super.channelRead(ctx, msg);
    }
}

处理器C示例代码:

/**
 * @program: learnnetty
 * @description: 处理器C
 * @create: 2020-05-08 16:42
 **/
public class InboundHandlerC extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("InboundHandlerC:" + msg);
        super.channelRead(ctx, msg);
    }
}

输出:

InboundHandlerA:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerB:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerC:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)

更换Server中Handler的顺序:

/**
 * @program: learnnetty
 * @description: 事件传播
 * @create: 2020-05-08 16:40
 **/
public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel
                                .pipeline()
                                .addLast(new InboundHandlerC())
                                .addLast(new InboundHandlerA())
                                .addLast(new InboundHandlerB());
                    }
                });

        bootstrap.bind("127.0.0.1", 8080);
    }
}

更改顺序后的输出:

InboundHandlerC:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerA:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerB:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)

可以看到读处理器的处理顺序与在引导类中添加处理器的顺序有关。

ChannelOutboundHandler的事件传播

Server端示例代码:

/**
 * @program: learnnetty
 * @description: 事件传播
 * @create: 2020-05-08 16:40
 **/
public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel
                                .pipeline()
                                .addLast(new InboundHandlerA())
                                .addLast(new OutboundHandlerA())
                                .addLast(new OutboundHandlerB())
                                .addLast(new OutboundHandlerC());
                    }
                });

        bootstrap.bind("127.0.0.1", 8080);
    }
}

用于做出反馈信息的HandlerA:

/**
 * @program: learnnetty
 * @description: 处理器A
 * @create: 2020-05-08 16:41
 **/
public class InboundHandlerA extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
        ctx.channel().writeAndFlush(Unpooled.wrappedBuffer("1".getBytes()));
    }
}

写处理器HandlerA:

/**
 * @program: learnnetty
 * @description: 处理器A
 * @create: 2020-05-08 16:54
 **/
public class OutboundHandlerA extends ChannelOutboundHandlerAdapter {
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        System.out.println("OutboundHandlerA:" + msg);
        super.write(ctx, msg, promise);
    }
}

写处理器HandlerB:

/**
 * @program: learnnetty
 * @description: 处理器B
 * @create: 2020-05-08 16:55
 **/
public class OutboundHandlerB extends ChannelOutboundHandlerAdapter {
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        System.out.println("OutboundHandlerB:" + msg);
        super.write(ctx, msg, promise);
    }
}

写处理器HandlerC:

/**
 * @program: learnnetty
 * @description: 处理器C
 * @create: 2020-05-08 16:55
 **/
public class OutboundHandlerC extends ChannelOutboundHandlerAdapter {
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        System.out.println("OutboundHandlerC:" + msg);
        super.write(ctx, msg, promise);
    }
}

输出:

OutboundHandlerC:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)
OutboundHandlerB:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)
OutboundHandlerA:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)

根据输出可以看到写处理器的执行顺序与在引导类中添加的顺序相反。

完整的Server示例代码:

/**
 * @program: learnnetty
 * @description: 事件传播
 * @create: 2020-05-08 16:40
 **/
public class Server {
    public static void main(String[] args) {
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();

        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel
                                .pipeline()
                                .addLast(new InboundHandlerA())
                                .addLast(new InboundHandlerB())
                                .addLast(new InboundHandlerC())
                                .addLast(new OutboundHandlerA())
                                .addLast(new OutboundHandlerB())
                                .addLast(new OutboundHandlerC());
                    }
                });

        bootstrap.bind("127.0.0.1", 8080);
    }
}

输出:

InboundHandlerA:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerB:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
InboundHandlerC:PooledUnsafeDirectByteBuf(ridx: 0, widx: 2, cap: 1024)
OutboundHandlerC:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)
OutboundHandlerB:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)
OutboundHandlerA:UnpooledHeapByteBuf(ridx: 0, widx: 1, cap: 1/1)

根据输出得到以下流程:
InboundHandler与OutboundHandler
虽然InboundHandler与OutboundHandler在同一个双向链表中,但是这两类Handler分工是不同的,通常是同类之间传播事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值