使用Netty 构造一个异步的httpclient

本文详细介绍了如何使用Netty库构建一个异步HTTP客户端,包括创建客户端实例、发起请求、处理响应等核心步骤。通过示例代码演示了如何通过Netty的`HttpClient`、`ChannelPipeline`和特定的`Handler`来实现HTTP访问,以及如何通过`ChannelFuture`和`ChannelPipeline`来异步处理网络请求和响应。

使用Netty 构造一个异步的httpclient


   这篇文档目的是通过一个 Netty构造的Http客户端demo,来说名如何使用 Netty。

1   示例代码
     HttpClient.java  


2 Httpclient 使用方法,详见代码HttpClient.java中main函数。
     HttpClient   hc  =   new   HttpClient ();
      ChannelPipeline line   hc . get ( "http://www.sohu.com" )
    line . addLast ( "handler" ,   new   HttpResponseHandler ());
    
    第一步构造HttpClient实例hc ,hc是可以反复使用的,可以多线程 多个请求的并发使用。
    第二步使用HttpCleint的get方法访问sohu首页。HttpCleint支持Http的GET PUT HEAD......方法。与其对应的是函数成员函数get put head......。
    第三步get方法(其他方法如 put post...也一样) 会返回一个ChannelPipeline ,line维护着一个或者多个handler 用于异步的处理I/O数据,如HttpResponseHandler是一个处理get访问返回数据的handler。这里向line里添加了一个handler 也可以添加多个。
    此段代码不会阻塞,都是立即返回。

3 代码详情
    下边吧程序展开成顺序执行的代码 来说明。
   a 主要流程

             //以下代码在 HttpClient.java HttpClient()中
            bootstrap = new ClientBootstrap( 
                                        new NioClientSocketChannelFactory(                                  
                                                    Executors.newCachedThreadPool(),                            
                                                    Executors.newCachedThreadPool()
                                                                                            )
                                                           );
            bootstrap.setPipelineFactory(new HttpClientPipelineFactory()); 

 
    ClientBootstrap 是Netty中的助手类。帮助建立Netty程序,维护主要的Netty类。如bootstrap 包括一个    
    ChannelFactory,一个PipelineFactory,
    Channel,Pipeline的作用和使用方法后边介绍。然后程序进行如下:
    
             //以下代码在 HttpClient.java retrieve()中
              ChannelFuture future = bootstrap.connect(new InetSocketAddress(“host”, port));
              future.addListener(new ConnectOk(request));



     bootstrap.connect方法是打开一个channel,这里可以看出channel是一个类似链接,事实上channel确实是Netty抽象出来的“链接”,统一了tcp udp  Nio Oio等网络接口的访问方式。 而这个channel 是由ChannelFactory产生的, NioClientSocketChannelFactory  打开的Channel使用了java的Nio 异步接口。所以coonect方法并没有返回一个Channel 而是一个 ChannelFuture。 ChannelFutre提供添加一个addListener的方法,使得这个channel真正被打开的时候
调用用户设置的回调。这里使用自定一个的一个类ConnectOk    (实现了ChannelFutureListener接口)。当channel被真正打开的时候,会调用ConnectOk     的operationComplete方法。operationComplete方法里才可以往channel里写入请求。
在写入之前 还得做些工作。如下:
     
             //以下代码在 HttpClient.java retrieve()中,略有区别
               ChannelPipeline line  = future.getChannel().getPipeline();
             line . addLast ( "handler" ,   new   HttpResponseHandler ());

      这些代码的目的就是设置 等到网络应答,也就是获得http响应后应做哪些工作。ClientBootstrap 会为每个channel生成一个ChannelPipeline。ChannelPipeline的作用就是处理channel上的数据。至于如何处理就要看ChannelPipeline上有哪些ChannelHandler,下边详述 先看ChannelPipeline是如何产生的。
      ClientBootstrap 中包含了一个HttpClientPipelineFactory 这是一个实现了ChannelPipelineFactory接口的getPipeline方法的类。 在getPipeline方法中可以按照自己需求定义生成一个PipeLine。
 
             //以下代码在 HttpClientPipelineFactory.java getPipeline()中
             ChannelPipeline pipeline = pipeline();
             pipeline.addLast("decoder", new HttpResponseDecoder());
             pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
             pipeline.addLast("encoder", new HttpRequestEncoder());

       这里根据自己定义生成一个pipeline。 pipeline()是Netty提供的生成pipeline的静态函数。因为要做的是http访问所以在getPipeline中配置了 Netty提供的访问http的几个ChannelHandler。分别是把http响应数据解码成HttpResponse对象的HttpResponseDecoder,合并chunk数据的HttpChunkAggregator,把HttpRequest对象编码成http请求协议的HttpRequestEncoder。  ChannelPipeline不仅设置了处理channel的handler 而且设置了处理顺序 ,这个可以参考文档。大体顺序是从channel流入的数据一步步被解析生成为程序的对象,流出的时候是把程序中的对象一步步解析生成通讯协议。
        在设置好这些后。可以往channel里边写入数据了。 
           
             //以下代码在 HttpClient.java ConnectOk类中 operationComplete ()中
            Channel channel = future.getChannel();                                                                            
            channel.write(request);    

        上边说到当channel真正被打开后会调用ConnectOk的operationComplete方法。在这里可以获得这个准备好的channel 然后调用write方法。这可以看到往channel里边写入了一个 HttpRequest对象。这个HttpRequest对象会被pipeline 编码成http请求最终发给服务器。注意write放法也是异步的,它会马上返回一个
ChannelFuture 对象。如果想要在write完成后做点什么 可以给这个ChannelFuture对象添加一个Listener 等待回调。
        等得到http应答后 pipeline会把channel中的数据一步步解析成HttpResponse对象,里边包括了 header cookie request ....一切信息。后边就是提供一个自己定义的handler 来处理这个response

       代码的基本流程就是这样。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值