2012-02-22 13 views
3

HTTPキープアライブ接続を使用するHTTPクライアントを作成しようとしています。私がClientBoostrapから接続すると、私はチャンネルを取得します。複数のHTTPリクエストを送信するためにこれを再利用できますか? HTTPキープアライブ機能を示す例はありますか?Nettyを使用してHttpキープアライブ接続を処理する方法

また別の質問があります。今私のクライアントはキープアライブ接続なしで動作します。私はClientHandlerのmessageReceivedメソッドでchannel.closeを呼び出しています。しかし、接続が閉じていないと思われ、しばらくしてソケットがなくなり、BindExceptionが得られます。すべてのポインタは本当に感謝されます。このようなコードの行によって

おかげ

答えて

2

限り接続ヘッダは(不明も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()」はこれを処理する理想的な方法ではありません。 –

+0

これは答えにも関係しませんが、例のメインスレッドをブロックするだけです – jkschneider