引导应用程序-Netty笔记(八)

Bootstrap 类

引导类的层次结构中包括了一个抽象的父类和两个具体的引导子类:

引导应用程序-Netty笔记(八)

ServerBootstrap 致力于使用一个父 Channel 来接受来自客户端的连接,并创建子 Channel 以用于它们之间的通信。Bootstrap 一般只需要一个单独的、没有父 Channel 的 Channel 来用于所有的网络交互。

引导客户端和无协议连接

Bootstrap 类被用于客户端或者使用了无连接协议的应用程序中,Bootstrap 类的 API :

  • Bootstrap group(EventLoopGroup):设置用于处理 Channel 所有事件的 EventLoopGroup
  • Bootstrap channel(Class) / Bootstrap channelFactory( ChannelFactory):channel() 方法指定了 Channel 的实现类。如果该实现类没提供默认的构造函数,可以通过调用 channelFactory() 方法来指定一个工厂类,它将会被 bind() 方法调用
  • Bootstrap localAddress(SocketAddress):指定 Channel 应该绑定到的本地地址。如果没有指定, 则将由操作系统创建一个随机的地址。或者,也可以通过 bind() 或 connect() 方法指定 localAddress
  • Bootstrap option( ChannelOption option, T value):设置 ChannelOption,其将被应用到每个新创建的 Channel 的 ChannelConfig。这些选项将会通过 bind() 或者 connect() 方法设置到 Channel,不管哪个先被调用。这个方法在 Channel 已经被创建后再调用 将不会有任何的效果。支持的 ChannelOption 取决于使用的 Channel 类型
  • Bootstrap attr(Attribute key, T value):指定新创建的 Channel 的属性值。这些属性值是通过 bind() 或者 connect() 方法设置到 Channel 的,具体取决于谁最先被调用。这个方法在 Channel 被创建后将不会有任何的效果
  • Bootstrap handler(ChannelHandler):设置将被添加到 ChannelPipeline 以接收事件通知的 ChannelHandler
  • Bootstrap clone():创建一个当前 Bootstrap 的克隆,其具有和原始的 Bootstrap 相同的设置信息
  • Bootstrap remoteAddress(SocketAddress):设置远程地址,也可以通过 connect() 方法来指定它
  • ChannelFuture connect():连接到远程节点并返回一个 ChannelFuture,其将会在连接操作完成后接收到通知
  • ChannelFuture bind():绑定Channel 并返回一个 ChannelFuture ,其将会在绑定操作完成后接收到通知,在那之后必须调用 Channel.connect()方法来建立连接

引导客户端

Bootstrap 类负责为客户端和使用无连接协议的应用程序创建 Channel :

引导应用程序-Netty笔记(八)

引导一个使用了 NIO TCP 传输的客户端:

Channel 和 EventLoopGroup 的兼容性

相互兼容的 EventLoopGroup 和 Channel :

引导应用程序-Netty笔记(八)

引导的时候 EventLoopGroup 和 Channel 要用同类前缀,比如上面我们实例里用到的 NioEventLoopGroupNioSocketChannel ,否则会导致 IllegalStateException 异常。

引导服务器

ServerBootstrap 类的 API :

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

ServerChannel 的实现负责创建子 Channel ,这些子 Channel 代表了已被接受的连接。ServerBootstrap 在 bind() 方法被调用时创建了一个 ServerChannel ,并且该 ServerChannel 管理多个子 Channel 。

引导应用程序-Netty笔记(八)

引导服务器:

从 Channel 引导客户端

假设你的服务器正在处理一个客户端的请求,这个请求需要它充当第三方系统的客户端。当一个应用程序(如一个代理服务器)必须要和组织现有的系统(如 Web 服或数据库)集成时,就可能发生这种情况。这种情况下,将需要从已经被接受的子 Channel 中引导一个客户端 Channel 。

通过将已被接受的子 Channel 的 EventLoop 传递给 Bootstrap 的 group() 方法来共享该 EventLoop 。因为分配给 EventLoop 的所有 Channel 都使用同一个线程,所以这避免了额外的线程创建,以及相关的上下文切换。

引导应用程序-Netty笔记(八)

从 Channel 引导客户端:

在引导过程中添加多个 ChannelHandler

引导服务器和使用 ChannelInitializer ,将多个 ChannelHandler 添加到一个 ChannelPipeline 中:

自定义 ChannelInitializer 实现类:

使用 Netty 的 ChannelOption 和属性

Bootstrap 可以通过 option() 方法来设置 ChannelOption ,引导创建的所有 Channel 都会被应用到 ChannelOption 中设置的值。包括底层连接的详细信息,如 keep-alive 或者超时属性以及缓冲区的设置。

在某些常用的属性和数据不可用时,Netty 提供了 AttributeMap (一个由 Channel 和引导类提供的集合)抽象以及 AttributeKey<T> (一个用于插入和获取属性值的泛型类)。可以安全地将任何类型的数据与客户端和服务器 Channel 相关联了。例如,跟踪用户和 Channel 之间的关系的服务器应用程序,可以通过将用户的 ID 存储为 Channel 的一个属性来完成。类似的技术可以被用来基于用户的 ID 将信息路由给用户,或者关闭活动较少的 Channel 。

使用属性值:

引导 DatagramChannel

Netty 提供了各种 DatagramChannel 的实现,用于无连接的协议。和前面基于 TCP 协议的 SocketChannel 唯一的区别是引导类不用再调用 connect() 方法,而是调用 bind() 方法。

使用 Bootstrap 和 DatagramChannel :

关闭

引导让应用程序启动并运行起来,但是关闭的时候也需要优雅的关闭。需要关闭 EventLoopGroup ,它将处理任何挂起的事件和任务,并且随后释放所有活动的线程。这就是调用 EventLoopGroup.shutdownGracefully() 方法的作用。这个方法是一个异步的操作,需要阻塞等待直到它完成,或者给返回的 Future 注册一个 监听器。

优雅关闭:

或者,也可以在调用 EventLoopGroup.shutdownGracefully() 方法之前,显式地在所有活动的 Channel 上调用 Channel.close() 方法。但是在任何情况下,都记得关闭 EventLoopGroup

    A+
发布日期:2019年04月19日  所属分类:Java
标签:
六阿哥

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: