具有同步请求响应的Netty客户端

时间:2014-05-30 08:39:03

标签: java http synchronization httprequest netty

我正在尝试基于netty创建一个http客户端。我已经根据Netty站点中给出的HttpSnoopClient example编写了代码。但问题是HttpResponse由HttpSnoopClientHandler&处理。 HttpRequests在HttpSnoopClient&我想同步它。如果我发送请求,我想确保一旦我知道对前一个的响应,我将发送下一个请求。但由于两者都是在不同的阶层处理,因此也很难做到这一点。

我做的一件事是在HttpTarget&中创建一个setResponse()方法。当HttpSnoopClientHandler从服务器接收到响应时,它将设置HttpResponse。但我不认为这是一个很好的方法,因为我无法知道reposne是针对哪个请求。

所以基本上我想同步这样做,即在HttpSnoopClient中发送请求(channel.writeandFlush(req)),然后等待HttpSnoopCLientHandler&收到响应。一旦收到HTTP 1.1 200 OK,就发送下一个请求。

任何人都可以告诉我这样做的好方法。提前谢谢!

2 个答案:

答案 0 :(得分:0)

我有一个类似的用例,我必须阻止并发请求,直到一个资源完成。我实现了一个ConcurrentHashMap<RequestKey, ArrayList<ChannelHandlerContext>>>,它将保存所有并发请求ChannelHandlerContext(ctx),并在第一个请求完成时引发一个事件,该事件将触发所有其他ctx使用缓存的响应。在所有这些中,我必须确保将AUTO_READ设置为false,以便对每个通道上的读取进行细粒度控制。

channelRead - &gt;

if(map.contains(reqKey)){
    map.add(reqKey, list.add(ctx))
    //do nothing with AUTO_READ = false and do not initiate any ctx.* methods
}else{
    //firstRequest
    map.add(reqKey, new ArrayList<CTX>(){{ add(ctx);}})
    //continue with request execution
    //cache response and raise event on completion
}

userEventTriggered - &gt;

onCompletionEvent {

    ctxList = map.get(reqKey).clone();
    map.remove(reqKey);
    for(blockedCtx : ctxList){
        //respond back with cached response to each blockedCtx
    }

}

@ norman-maurer你愿意接受这个!!! //

答案 1 :(得分:0)

当你为每个连接创建一个新的HttpSnoopClientHandler时,我会考虑将HttpSnoopClientHandler转换为ChannelDuplexHandler。在write方法中,您可以存储对传出http请求的引用。收到响应后,您可以使用(通道,请求,响应)调用setResponse方法。这应该提供足够的上下文,以便您可以正确处理响应。

如果您的客户端是纯请求/响应,不会单独发出不相关的请求,并且您希望应用程序线程按顺序处理响应,那么您可以使用SynchronousQueue协调响应并允许主线程继续。或者,您的回调可以在内部处理响应。

您还可以扩展此技术以使用HTTP流水线。 HTTP流水线保证响应按发出请求的顺序返回。在HttpSnoopClientHandler中,您维护一个请求队列。返回每个响应时,您将其与队列前面的请求进行匹配。