Netty笔记(八) Bootstrap

    Netty提供了应用启动的配置跟启动API,服务端:ServerBootstarp,客户端Bootstarp。

    他们用来指定

    EventLoopGroup

    Channel

    ChannelOptions

    当Channel注册时,调用ChannelHandler

    设置Attributes到指定Chanel。

    绑定IP跟端口

    ServerBootstarp绑定端口使用bind()。Bootstarp连接使用connect()。

    关系:


    客户端Bootstarp提供了以下方法:

group(..) : 设置EventLoopGroup,用于服务Channel中I/O操作

channel(..) 、channelFacotry(..) :  指定使用Channel。 NIO/OIO...

localAddress(...) :设置本地地址,端口

option(...) : 设置Channel的配置

attr(..) : 设置Channel的附加属性

handler(..) : 设置定义的ChannelHandler到ChannelPipeline中

clone() : 拷贝。

remoteAddress() : 设置远程连接地址,端口

connect() : 连接远程服务

bind()    : 绑定本地服务

Bootstarp,bind()创建Channel后,调用connect(),将会建立连接与Channel()绑定。

    若直接调用,则创建Channel 与建立的连接绑定。


Bootstrap bootstrap = new Bootstrap(); #1
bootstrap.group(new NioEventLoopGroup()) #2
.channel(NioSocketChannel.class) #3
.handler(new SimpleChannelInboundHandler<ByteBuf>() { #4
@Override
protected void channeRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
System.out.println("Reveived data");
byteBuf.clear();
}
});
ChannelFuture future = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80)); #5
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Connection established");
} else {
System.err.println("Connection attempt failed");
channelFuture.cause().printStackTrace();
}
}
});


注意:使用NioSocketChannel,则要与NioEventLoopGourp结对绑定,否则报错,OIO同理。


服务端ServerBootstrap
group(..) : 设置EventLoopGroup,用于服务ServerChannel的I/O操作与接收Channels

channel(..)、channelFacotry : 设置ServerChannel

localAddress(...) : 设置ServerChannel绑定地址与端口

option(...) : 设置ServerChannel的配置

childOption(...) : 设置ServerChannel accept 并创建的 Channel的配置

attr(...)    : 设置ServerChannel的额外属性

childAttr(...) : 设置ServerChannel accept 并创建的  Channel的额外属性

handler(...) : ServerChannel的ChannelHandler,有默认实现,无特别需求不指定

childHandler(...) : 设置由ServerChanel accpet到创建的Chanel的ChannelHandler,每个ChannelHandler 对应的处理不同客户端I/O

clone()    : 拷贝

bind(...) : 绑定并启动服务。返回ChannelFutrue。


ServerBootstrap bootstrap = new ServerBootstrap(); #1
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()) #2
.channel(NioServerSocketChannel.class) #3
.childHandler(new SimpleChannelInboundHandler<ByteBuf>() { #4
@Override
protected void channelRead0(ChannelHandlerContext ctx,
ByteBuf byteBuf) throws Exception {
System.out.println("Reveived data");
byteBuf.clear();
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080)); #5
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bound attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
ServerBootstarp内嵌Bootstarp连接,共同EventLoop例子,使用场景,做代理,或服务端需要连接其他服务来获取数据处理。



ServerBootstrap bootstrap = new ServerBootstrap(); #1
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()) #2
.channel(NioServerSocketChannel.class) #3
.childHandler(new SimpleChannelInboundHandler<ByteBuf>() { #4
ChannelFuture connectFuture;
@Override
public void channelActive(ChannelHandlerContext ctx)
throws Exception {
Bootstrap bootstrap = new Bootstrap(); #5
bootstrap.channel(NioSocketChannel.class) #6
.handler(
new SimpleChannelInboundHandler<ByteBuf>() { #7
@Override
protected void channelRead0(
ChannelHandlerContext ctx,
ByteBuf in) throws Exception {
System.out.println("Reveived data");
in.clear();
}
});
bootstrap.group(ctx.channel().eventLoop()); #8
connectFuture = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80)); #9
}
@Override
protected void channelRead0(ChannelHandlerContext
channelHandlerContext, ByteBuf byteBuf) throws Exception {
if (connectFuture.isDone()) {
// do something with the data #10
}
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080)); #11
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound");
} else {
System.err.println("Bound attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
ServerBootstarp 需要支持多种协议。我们需要加入多个ChannelHandler时候,使用继承ChannelInitializer,并实现initChannel方法,便可以把 Channel加入到ChanelPipeline中,并且与EventLoopGroup关联。例子:



ServerBootstrap bootstrap = new ServerBootstrap(); #1
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()) #2
.channel(NioServerSocketChannel.class) #3
.childHandler(new ChannelInitializerImpl()); #4
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080)); #5
future.sync();
final class ChannelInitializerImpl extends ChannelInitializer<Channel> {#6
@Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline(); #7
pipeline.addLast(new HttpClientCodec());
pipeline.addLast(new HttpObjectAggregator(Integer.MAX_VALUE));
}
}
ChannelOptions and attributes


channelOptions 可以设置 Channel的连接超时,keep-alive等

attributes 可以设置一些用户自定义的值。

final AttributeKey<Integer> id = new AttributeKey<Integer>("ID"); #1
Bootstrap bootstrap = new Bootstrap(); #2
bootstrap.group(new NioEventLoopGroup()) #3
.channel(NioSocketChannel.class) #4
.handler(new SimpleChannelInboundHandler<ByteBuf>() #5
@Override
public void channelRegistered(ChannelHandlerContext ctx)
throws Exception {
Integer idValue = ctx.channel().attr(id).get(); #6
// do something with the idValue
}
@Override
protected void channelRead0(
ChannelHandlerContext channelHandlerContext,
ByteBuf byteBuf) throws Exception {
System.out.println("Reveived data");
byteBuf.clear();
}
});
bootstrap.option(ChannelOption.SO_KEEPALIVE,true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000); #7
bootstrap.attr(id, 123456); #8
ChannelFuture future = bootstrap.connect(
new InetSocketAddress("www.manning.com", 80)); #9
future.syncUninterruptibly();
使用UDP协议,跟Bootstarp有一点不同的是,不需要bind() 或 connect() 操作

Bootstrap bootstrap = new Bootstrap();
bootstrap.group(new OioEventLoopGroup()).channel(OioDatagramChannel.class)
.handler(new SimpleChannelInboundHandler<DatagramPacket>(){
@Override
public void channelRead0(ChannelHandlerContext ctx,
DatagramPacket msg) throws Exception {
// Do something with the packet
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(0));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture)
throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Channel bound");
} else {
System.err.println("Bound attempt failed");
channelFuture.cause().printStackTrace();
}
}
});



转载于:https://my.oschina.net/XzhiF/blog/265584

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值