`
fengshihao
  • 浏览: 49436 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用Netty 构造一个异步的httpclient

    博客分类:
  • java
阅读更多

使用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

       代码的基本流程就是这样。

2
1
分享到:
评论
2 楼 403259982 2012-11-16  
hanwesley 写道
兄弟你的get,post方法上为什么返回ChannelPipline呢,不应该是返回CannelFuture吗?
如果按照你这样的连接都关闭了,你根本就没有办法在客户端显示响应结果了啊,关闭连接也应该是在结果返回给客户端再关闭吧?


兄弟,你还是没理解异步的作用啊。。。你的想法还停留在同步。
1 楼 hanwesley 2011-07-22  
兄弟你的get,post方法上为什么返回ChannelPipline呢,不应该是返回CannelFuture吗?
如果按照你这样的连接都关闭了,你根本就没有办法在客户端显示响应结果了啊,关闭连接也应该是在结果返回给客户端再关闭吧?

相关推荐

    netty-http-client:Java中的一个异步http客户端,它使用Netty 4.x,具有基于回调的干净API

    使用Netty 4.x的Java异步HTTP客户端,具有干净的,基于回调的API。 该API受到 http模块的启发; 它旨在(主要)避免使用Future模式,并通过回调来开展业务。 我们尽可能避免引入复杂的抽象,这些抽象试图隐藏HTTP...

    java开源包3

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包8

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包1

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包11

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包2

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包6

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包5

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包10

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包4

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包7

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    java开源包9

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    JAVA上百实例源码以及开源项目源代码

    一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java...

    java开源包101

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    Java资源包01

    jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。提供了一个基于对象模型的 ActionScript 字节码,并提供了 ActionScript 字节码统计工具。 Java类重加载工具 JReloader JReloader 是一个用来重新...

    JAVA上百实例源码以及开源项目

    一个目标文件,演示Socket的使用。 Java 组播组中发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java...

Global site tag (gtag.js) - Google Analytics