一、引导
1.1 什么是引导
引导一个应用程序是指对它进行配置,并使它运行起来的过程。引导可以简单的认为是将分散的了 ChannelPipeline、ChannelHandler 和 EventLoop组合起来,成为一个完成应用程序的模块。
1.2 Bootstrap 类
引导类的层次结构包括一个抽象的父类和两个具体的引导子类。
相对于将具体的引导类分别看作用于服务器和客户端的引导来说,它们的本意是用来支撑不同的应用程序的功能。
服务器致力于使用一个父 Channel 来接受来自客户端的连接,并创建子Channel 以用于它们之间的通信;
而客户端将最可能只需要一个单独的、没有父 Channel 的 Channel 来用于所有的网络交互。
如 UDP,因为它们并不是每个连接都需要一个单独的 Channel。
我们在前面的几篇中学习的几个 Netty 组件都参与了引导的过程,而且其中一些在客户端和服务器都有用到。两种应用程序类型之间通用的引导步骤由 AbstractBootstrap 处理,而特定于客户端或者服务器的引导步骤则分别由 Bootstrap 或 ServerBootstrap 处理。
AbstractBootstrap类申明:
public abstract class AbstractBootstrap
<B extends AbstractBootstrap<B,C>,C extends Channel>
在这个签名中,子类型 B 是其父类型的一个类型参数,因此可以返回到运行时实例的引用以支持方法的链式调用(也就是所谓的流式语法)。
它的子类有两种申明方式,分别为:
public class Bootstrap
extends AbstractBootstrap<Bootstrap,Channel>
public class ServerBootstrap
extends AbstractBootstrap<ServerBootstrap,ServerChannel>
是不是有些眼熟?我们在第二篇博文中使用过他们构建过客户端和服务端。
1.3 引导客户端和无连接协议
Bootstrap 类被用于客户端或者使用了无连接协议的应用程序中,它的大部分方法都继承自 AbstractBootstrap 类。
名 称 |
描 述 |
Bootstrap group(EventLoopGroup) |
设置用于处理 Channel 所有事件的 EventLoopGroup |
Bootstrap channel(Class<? extends C>) Bootstrap channelFactory(ChannelFactory<? extends C>) |
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()方法来建立连接 |
这玩意太多了,建议可以收藏本文,用的时候翻出来看一看即可。
1.4 引导客户端
Bootstrap 类负责为客户端和使用无连接协议的应用程序创建 Channel。
它的引导过程可以参见下面的图示:
我们来一段引导了一个使用 NIO TCP 传输的客户端代码看看:
package com.example.netty.bootstrap.niotcp;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.net.InetSocketAddress;
/**
* @author lhd
* @date 2023/05/24 15:19
* @notes 引导了NIO 的 Netty 客户端代码
*/
public class client {
public static void main(String[] args) {
EventLoopGroup group = new NioEventLoopGroup();
//创建一个Bootstrap类的实例以创建和连接新的客户端Channe
Bootstrap bootstrap = new Bootstrap();
//设置 EventLoopGroup,提供用于处理 Channel事件的 EventLoop
bootstrap.group(group)
//指定channel实现
.channel(NioSocketChannel.class)
//设置用于 Channel 事件和数据的ChannelInboundHandle
.handler(new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
System.out.println("Received