netty(七)--Bootstrap
引导一个应用程序是指对它进行配置,并使他运行起来的过程。
服务器致力于使用一个父 Channel 来接受
来自客户端的连接, 并创建子 Channel 以用于它们之间的通信;而客户端将最可能只需要一个
单独的、 没有父 Channel 的 Channel 来用于所有的网络交互。
bootstrap类的API
名称 | 描述 |
---|---|
Bootstrap group(EventLoopGroup g) | 设置用于处理channel所有事件的eventLoop |
Bootstrap channel(class),Bootstrap channelFactory | 指定channel的实现类,或者工厂类作为参数 |
Bootstrap localAddress(socketaddress) | 指定channel应该绑定的本地地址。指定channel应该绑定到的地址,如果没有指定,将由操作系统创建一个随机的地址。或者,也可以通过bind()或者connect方法指定localAddress |
Bootstrap option(channelOption,T) | 设置channelOption,其将被应用到每个新创建的channel的channelConfig。这些选项将会通过bind或者connect方法设置到channel。这个方法对于已经被创建的线程无效 |
Bootstrap attr(key,val) | 指定新创建的channel属性值,作用同上 |
Bootstrap handler(ChannelHandler) | 设置将被添加到ChannelPipeline以接收事件通知的channelHandler |
Bootstrap clone() | 创建一个Boostrap的克隆,具有和原始bootstrap相同的设置信息 |
Boostrap remoteAddress | 设置远程地址,或者通过connect方法指定 |
channelFuture connect() | 连接到远程节点并返回一个channelFuture,其将会在连接操作完成后接到通知 |
channelFuture bind() | 绑定channel并返回一个channelFuture,其将会在绑定操作完成后接收到通知,在那之后必须调用channel,connect方法来建立连接。 |
引导客户端
bootstrap类负责为客户端和使用无连接协议的应用程序创建channel。
channel和EventLoopGroup的兼容性
不能混用具有不同前缀的组件。
在引导的过程中,在调用 bind()或者 connect()方法之前,必须调用以下方法来设置所需的组件:
- group();
- channel()或者 channelFactory();
- handler()。
如果不这样做, 则将会导致 IllegalStateException。对 handler()方法的调用尤其重要,因为它需要配置好 ChannelPipeline。
引导服务器
ServerBootstrap类的方法
名称 | 描述 |
---|---|
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。 |
attr | 指定serverChannel的属性,属性将通过bind方法设置给channel |
childAttr | 将属性设置给已经被接受的子channel |
handler | 设置被添加到serverChannel的channelPipeline中的channelHandler |
childHandler | 设置将被添加到的已被接受的子channel的channelpipeline中的channelhandler。 |
bind | 绑定serverChannel并且返回一个ChannelFuture,其将在绑定操作完成后收到通知 |
ServerChannel 的实现负责创建子 Channel,这些子 Channel 代表了已被接受的连接。
假设你的服务器正在处理一个客户端的请求, 这个请求需要它充当第三方系统的客户端。当一个应用程序(如一个代理服务器)必须要和组织现有的系统(如 Web 服务或者数据库)集成时,就可能发生这种情况。 在这种情况下,将需要从已经被接受的子 Channel 中引导一个客户端 Channel。
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(
new SimpleChannelInboundHandler<ByteBuf>() {
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class).handler(
new SimpleChannelInboundHandler<ByteBuf>() {
@Override
protected void channelRead0(
ChannelHandlerContext ctx, ByteBuf in)
throws Exception {
System.out.println("Received data");
}
} );
bootstrap.group(ctx.channel().eventLoop());
connectFuture = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80));
}
@Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {
// do something with the data
}
}
} );
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bind attempt failed");
channelFuture.cause().printStackTrace();
}
}
} );
在引导过程中添加多个 ChannelHandler,使用自定义的ChannelInitializer。
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpClientCodec());
}
待续。。。