Netty3 源码分析 - ClientBootstrap



Bootstrap是通道初始化辅助类 提供了初始化通道或子通道所需要的数据结构,那么ClientBootstrap就是客户端的,而且会执行连接操作。

配置通道,就是把相应的键值对选项传递给底层:
 ClientBootstrap b = ...;
 // Options for a new channel
 b.setOption("remoteAddress", new InetSocketAddress("example.com", 8080));
 b.setOption("tcpNoDelay", true);
 b.setOption("receiveBufferSize", 1048576);

配置通道流水线,每个通道有自己的pipeline,建议的方式是调用Bootstrap.setPipelineFactory(ChannelPipelineFactory)来制定ChannelPipelineFactory 
 ClientBootstrap b = ...;
 b.setPipelineFactory(new MyPipelineFactory());

 public class MyPipelineFactory implements ChannelPipelineFactory {
   public ChannelPipeline getPipeline() throws Exception {
     // Create and configure a new pipeline for a new channel.
     ChannelPipeline p = Channels.pipeline();
     p.addLast("encoder", new EncodingHandler());
     p.addLast("decoder", new DecodingHandler());
     p.addLast("logic",   new LogicHandler());
     return p;
   }
 }

另一种方式,只在特定情况下适用(在Bootstrap的源码中有解释),就是利用默认的pipeline,并且让新的Channel来浅拷贝它:
 ClientBootstrap b = ...;
 ChannelPipeline p = b.getPipeline();

 // Add handlers to the default pipeline.
 p.addLast("encoder", new EncodingHandler());
 p.addLast("decoder", new DecodingHandler());
 p.addLast("logic",   new LogicHandler());

浅拷贝意味着默认pipeline里面的Handler,只是他们的引用增加到了新的ChannelPipeline中,所以要注意那些Handler是否有副作用。所以不适合在服务器端为每个新来的连接打开一个Channel的情况,为不同的Channel定制不同的配置。

此外ClientBootstrap只是一个辅助类,没有分配和管理任何资源,真正管理资源的是构造器中传入的ChannelFactory的实现,所以用同样的ChannelFactory 来构造多个Bootstrap实例,为不同的通道应用不同的设置是完全OK的。

bind方法: 绑定操作,在绑定和连接需要分开的时候用到。 比如在尝试连接之前,可以通过Channel.setAttachment(Object)为这个通道设置一个attachment 这样一旦连接建议,就可以访问这个attachment。
  ChannelFuture bindFuture = bootstrap.bind(new InetSocketAddress("192.168.0.15", 0));
  Channel channel = bindFuture.getChannel();
  channel.setAttachment(dataObj);
  channel.connect(new InetSocketAddress("192.168.0.30", 8080));
在ChannelHandler中可以向下面这样访问。
  public class YourHandler extends SimpleChannelUpstreamHandler {
      public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
          Object dataObject = ctx.getChannel().getAttachment();
      }
  }

详细的源码注释可以看我的Github。






郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。