StackDoc

StackDoc

當前位置: 主頁 > 服務器軟件 > Jboss >

使用Netty 構造一個異步的httpclient

時間:2010-10-02 06:56來源:互聯網 作者:互聯網 點擊:
原文地址: http://dev.firnow.com/course/3_program/java/javajs/20100719/454049.html 使用Netty構造一個異步的httpcli

原文地址: http://dev.firnow.com/course/3_program/java/javajs/20100719/454049.html

使用Netty構造一個異步的httpclient


這篇文檔目的是通過一個Netty構造的Http客戶端demo,來說名如何使用Netty。

1示例代碼
?? ? HttpClient.java
?? ? HttpClientPipelineFactory.java
?? ? HttpResponseHandler.java


2 Httpclient使用方法,詳見代碼HttpClient.java中main函數。
?? ? HttpClient hc = new HttpClient ();
????? ChannelPipeline line = hc . get ( "http://www.sohu.com" )ng: 0px; margin: 0px;"> 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 NioClientSocketChann elFactory(
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真正被打開的時候
調用用戶設置的回調。這裡使用自定一個的一個類ConnectOkt-size: small; padding: 0px; margin: 0px;"> (實現了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。

?? ??? ??? ? //以下代碼在</span> 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

代碼的基本流程就是這樣。


本文摘自:http://crazier9527.javaeye.com/blog/768684
頂一下
(1)
100%
踩一下
(0)
0%
------分隔線----------------------------
發表評論
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
評價:
表情:
驗證碼:點擊我更換圖片
欄目列表
推薦內容