2012-02-22 224 views
3

我正在嘗試編寫一個使用HTTP保持連接的HTTP客戶端。當我從ClientBoostrap進行連接時,我得到了該頻道。我可以重複使用它來發送多個HTTP請求嗎?是否有任何示例演示HTTP Keep Alive功能?如何使用Netty處理Http Keep-Alive連接

另外我還有一個問題。現在我的客戶端沒有保持連接狀態。我在ClientHandler的messageReceived方法中調用channel.close。但它似乎沒有關閉連接,一段時間後套接字用完了,我得到了一個BindException。任何指針將非常感激。

由於

回答

2

只要連接頭沒有設置由線的類似於此代碼爲CLOSE(和可能的HttpVersion是1.1,雖然不確定)...

request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE);

...您的頻道應該對多個請求/響應對保持打開狀態。

下面是一些示例代碼,我今天鞭打它來測試它。您可以在頻道關閉之前從Google反彈任意數量的請求:

public class TestHttpClient { 
    static class HttpResponseReader extends SimpleChannelUpstreamHandler { 
     int remainingRequests = 2; 

     @Override 
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { 
      HttpResponse response = (HttpResponse) e.getMessage(); 

      System.out.println("Beginning -------------------"); 
      System.out.println(new String(response.getContent().slice(0, 50).array())); 
      System.out.println("End -------------------\n"); 

      if(remainingRequests-- > 0) 
       sendRequest(ctx.getChannel()); 
      else 
       ctx.getChannel().close(); 
     } 
    } 

    public static void main(String[] args) { 
     ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory()); 
     bootstrap.setPipeline(Channels.pipeline(
       new HttpClientCodec(), 
       new HttpResponseReader())); 
     // bootstrap.setOption("child.keepAlive", true); // no apparent effect 

     ChannelFuture future = bootstrap.connect(new InetSocketAddress("google.com", 80)); 
     Channel channel = future.awaitUninterruptibly().getChannel(); 

     channel.getCloseFuture().addListener(new ChannelFutureListener() { 
      public void operationComplete(ChannelFuture future) throws Exception { 
       // this winds up getting called immediately after the receipt of the first message by HttpResponseReader! 
       System.out.println("Channel closed"); 
      } 
     }); 

     sendRequest(channel); 

     while(true) { 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private static void sendRequest(Channel channel) { 
     // Prepare the HTTP request. 
     HttpRequest request = new DefaultHttpRequest(
       HttpVersion.HTTP_1_1, HttpMethod.GET, "http://www.google.com"); 
     request.setHeader(HttpHeaders.Names.HOST, "google.com"); 
     request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); 

     channel.write(request); 
    } 
} 
+0

'sleep()'不可能是處理此問題的理想方法。 – 2015-08-04 09:19:53

+0

它也與答案無關,但在那裏阻止示例中的主線程 – jkschneider 2015-08-04 15:24:49