Netty 3 Bootstrap和Channel的生命周期

本文详细介绍了Netty 3中Bootstrap和Channel的生命周期,包括Bootstrap的结构、ServerBootstrap和Bootstrap的区别及其在服务端的创建过程。通过示例展示了如何设置ServerBootstrap,包括初始化ChannelPipeline、添加ChannelHandler以及处理生命周期的不同阶段。同时,文章讨论了服务端Channel的创建、连接建立、数据传输和关闭连接的过程,解释了Netty中相关的ChannelHandler和EventLoopGroup的角色。
摘要由CSDN通过智能技术生成
Netty 3 Bootstrap和Channel的生命周期




Bootstrap简介
Bootstrap :引导程序,将ChannelPipeline、ChannelHandler、EventLoop进行整体关联作用。
Bootstrap的结构中。定义了一个抽象父类,两个具体子类。


public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel>
     implements Cloneable

抽象类定义中,子类型B是父类型的一个类型参数??这样的泛型定义方式有啥好处???

public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>

public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel>

Bootstrap具体分为了两个实现,分别是服务端引导类和客户端引导类。
ServerBootstrap:用于服务端,使用一个ServerChannel来接受客户端的连接并创建出对应的子Channel。
Bootstrap:用于客户端,只需要一个单独的Channel,来与服务端进行数据交互,对应server端的子Channel。



ServerBootstrap实例程序和API

public void start(int port) throws Exception {
     EventLoopGroup bossGroup = new NioEventLoopGroup(1);
     EventLoopGroup workerGroup = new NioEventLoopGroup(nettyThread);
     try {
           ServerBootstrap b = new ServerBootstrap();
           b.group(bossGroup, workerGroup)
           .channel(NioServerSocketChannel.class) // (3)
        .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        // server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码
                        ch.pipeline().addLast(new HttpResponseEncoder());
                        // server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码
                        ch.pipeline().addLast(new HttpRequestDecoder());

                        ch.pipeline().addLast(new HttpObjectAggregator(nettyLength));
                        ch.pipeline().addLast(new HttpServerInboundHandler());
                    }
                }).option(ChannelOption.SO_BACKLOG, 128) // (5)
        .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

           ChannelFuture f = b.bind(port).sync();
           f.channel().closeFuture().sync();
     } finally {
           workerGroup.shutdownGracefully();
           bossGroup.shutdownGracefully();
     }
}
名称
描述
group 设置 ServerBootstrap 要用的 EventLoopGroup。这个 EventLoopGroup 将用于 ServerChannel 和被接受的子 Channel 的 I/O 处理
channel 设置将要被实例化的 ServerChannel 类
channelFactory 如果不能通过默认的构造函数 创建Channel,那么可以提供一个ChannelFactory
localAddress 指定 ServerChannel 应该绑定到的本地地址。如果没有指定,则将由操作系 统使用一个随机地址。或者,可以通过 bind()方法来指定该 localAddress
option 指定要应用到新创建的 ServerChannel 的 ChannelConfig 的 Channel- Option。这些选项将会通过 bind()方法设置到 Channel。在 bind()方法 被调用之后,设置或者改变 ChannelOption 都不会有任何的效果。所支持 的 ChannelOption 取决于所使用的 Channel 类型。参见正在使用的 ChannelConfig 的 API 文档
childOption 指定当子 Channel 被接受时,应用到子 Channel 的 ChannelConfig 的 ChannelOption。所支持的 ChannelOption 取决于所使用的 Channel 的类 型。参见正在使用的 ChannelConfig 的 API 文档
attr 指定ServerChannel上的属性,属性将会通过bind()方法设置给Channel。 在调用 bind()方法之后改变它们将不会有任何的效果
childAttr 将属性设置给已经被接受的子 Channel。接下来的调用将不会有任何的效果
handler 设置被添加到ServerChannel的ChannelPipeline中的ChannelHandler。 更加常用的方法参见childHandler()
childHandler 设置将被添加到已被接受的子Channel的ChannelPipeline中的Channel- Handler。handler()方法和 childHandler()方法之间的区别是:前者所 添加的 ChannelHandler 由接受子 Channel 的 ServerChannel 处理,而 childHandler()方法所添加的ChannelHandler将由已被接受的子Channel 处理,其代表一个绑定到远程节点的套接字
clone 克隆一个设置和原始的 ServerBootstrap 相同的 ServerBootstrap
bind 绑定 ServerChannel 并且返回一个 ChannelFuture,其将会在绑定操作完 成后收到通知(带着成功或者失败的结果)



在ServerBootstrap的创建过程中,通过channel()方法设置了需要被实例化ServerChannel类。
ServerChannel代表客户端和服务端之间的连接。不同的协议有对应不同的ServerChannel。可以从ServerChannel子接口中可以看出,对于不同的协议有不同的ServerChannel子接口。我们要使用的NioServerSocketChannel就是TCP协议的。Java nio中的形式使类似的,对于ServerSocketChannel还有对应的SocketChannel。

ServerSocketChannel和SocketChannel可以参考简单Java Nio通信的逻辑。客户端发起SocketChannel的通信,服务端通过ServerSocketChannel获取对应的SocketChannel。下面是普通Java Nio的服务端代码。
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(1234));

while (true) {
    SocketChannel socketChannel = serverSocketChannel.accept();
    if (socketChannel != null) {
        executor.submit(new SocketChannelThread(socketChannel));
    }
}


在初始化过程中添加多个ChannelHandler。
在初始化过程中调用handler或者childHandler方法可以用来添加单个ChannelHandler。但是正常使用中,对于一个Channel需要多个Handler处理,如果把所有处理的逻辑都放在一个Handler中会导致一个臃肿的类,并且毫无扩展性可言。
在Netty提供了一个ChannelInboundHandlerAdapter子类,ChannelInitializer。通过这个可以将多个Handler添加到一个ChannelPipeline中。在添加的过程中,需要注意ChannelHandler的添加顺序。将一些数据梳理的Handler放在前面,业务处理的则放在最后。例如Http服务,需要先将Netty的TCP数据封装成对应的HttpRequest之后我们才能方便使用。
在Netty中提供了常用的ChannelHandler,具体参考ChannelHandler中。
childHandler(new ChannelInitializer<SocketChannel>() { // (4)
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        // server端发送的是httpResponse,所以要使用HttpResponseEncoder进行编码
        ch.pipeline().addLast(new HttpResponseEncoder());
        // server端接收到的是httpRequest,所以要使用HttpRequestDecoder进行解码
        ch.pipeline().addLast(new HttpRequestDecoder());

        ch.pipeline().addLast(new HttpObjectAggregator(nettyLength));
        ch.pipeline().addLast(new HttpServerInboundHandler());
    }
})


服务端Channel的生命周期

Channel是服务端和客户端用于传输数据的通道,Channel服务维护套接字连接、IO操作等组件。下面以服务端的NioServerSocketChannel 和对应的NioSocketChannel作为例子。

对于TCP,甚至于所有有连接的传输层协议。都可以归纳为以下三个步骤:建立连接、数据传输、关闭连接。在服务的话需要提前监听端口,用于建立连接。

服务端ServerChannel

通过channel方法设定SeverChannel,通过代码可以看到,通过传入的clazz,构造了一个ReflectiveChannelFactory,并将其赋值到this.channelFactory中。用于后续创建ServerChannel的实例。
ServerBootstrap b = new ServerBootstrap();
....
b.channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128)


public B channel(Class<? extends C> channelClass) {
    if (channelClass == null) {
        throw new NullPointerException("channelClass");
    }
    return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
}
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值