简体   繁体   中英

How to call properly HTTP client from HTTP server request handler in netty?

I am developing custom HTTP server with.netty 3.3.1.

I need to implement something like this

  1. HTTP Server receives request
  2. HTTP Server parses it and invokes HTTP request as a client to other machine
  3. HTTP Server waits for the response of request sent in (2)
  4. HTTP Server sends response to request from (1) based on what had received in (3)

It means that client request (2) has to behave as synchronous.

What I wrote is based on HttpSnoopClient example but it does not work, because I receive

java.lang.IllegalStateException: 
await*() in I/O thread causes a dead lock or sudden performance drop. Use addListener() instead or call await*() from a different thread. 

I've refactored the code from the example mentioned above and now it looks more less like this (starting from line 7f of HttpSnoopClient):

    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
    future.addListener(new ChannelFutureListener() {
      public void operationComplete(ChannelFuture future) {
        if (!future.isSuccess()) {
          System.err.println("Cannot connect"); 
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
            return;
          }
          System.err.println("Connected");

          Channel channel = future.getChannel();

          // Send the HTTP request.
          channel.write(request);
          channel.close();



          // Wait for the server to close the connection.
          channel.getCloseFuture().addListener(new ChannelFutureListener() {
            public void operationComplete(ChannelFuture future) {
              System.err.println("Disconnected"); 
              bootstrap.releaseExternalResources(); // DOES NOT WORK?
            }
          });   
        }
    });

  } 
}

The run() command from the above example is invoked in the messageReceived function of my herver handler.

So it became asynchronous and avoid await* functions. Request is invoked properly. But - for uknown reason for me - the line

              bootstrap.releaseExternalResources(); // DOES NOT WORK?

does not work. It throws an exception saying that I cannot kill the thread I am currently using (which sounds reasonable, but still does not give me an answer how to do that in a different way).

I am also not sure is this a correct approach?

Maybe you can recommend a tutorial of such event programming techniques in.netty? How to deal - in general - with a few asynchronous requests that has to be invoked in specified order and wait for each other?

Thank you,

If you really want to release the bootstrap on close you can do it like this:

channel.getCloseFuture().addListener(new ChannelFutureListener() {
    public void operationComplete(ChannelFuture future) {
        System.err.println("Disconnected"); 
        new Thread(new Runnable() {
            public void run() {
                bootstrap.releaseExternalResources();
            }
        }).start();
    }
});   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM