2012-02-22 219 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