Question

I'm trying to create long polling Comet using Jboss Netty.

How can I configure time out of 30 sec? Following the documentaton:

@Override
    public ChannelPipeline getPipeline() throws Exception {
    ChannelPipeline pipeline = Channels.pipeline();
     pipeline.addLast("decoder", new HttpRequestDecoder());
     pipeline.addLast("encoder", new HttpResponseEncoder());
     pipeline.addLast("handler", new HTTPRequestHandler());
     Timer timer = new HashedWheelTimer();
     pipeline.addLast("timeout", new IdleStateHandler(timer, 30, 30, 0));
    return pipeline; 

but it doesn't work and my request lasts forever. How can this be solved?

Does it mean that I need to implement Callable<T>, then call Future.get with timeout parameter and terminate request if TimeOutException occurs? Then should I use Future<ChannelFuture>?

Is there any other approach?

Code:

FutureExecutor executor = FutureExecutor.getInstance();

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        HttpRequest request = (HttpRequest) e.getMessage();
    ChannelFuture channelFuture = null;
        Callable<ChannelFuture> myRunnable = new MyCallable(e);
        Future<ChannelFuture> future = executor.fireEvent(myRunnable);

    try{
        channelFuture = future.get(40,TimeUnit.SECONDS);
        }catch (TimeoutException ex) {

        channelFuture = e.getChannel(Response timeOutResponse);
               // handle the timeout
        } catch (InterruptedException ex) {
        channelFuture = e.getChannel(Response interaptedResponse);

        } catch (ExecutionException ex) {
            channelFuture = e.getChannel(Response errorResponse);
        } 
        finally{
            future.cancel(true);
            channelFuture.addListener(ChannelFutureListener.CLOSE);
        }

}

and inside of Callable I'm just monitoring BlockedQueue:

@Override
public ChannelFuture call() {
        final BlockingQueue<String> queue  =.....
        while (true){
        Message message = queue.take();
                ChannelBuffer partialresponse = ChannelBuffers.buffer(message.toJson());
         ChannelFuture future = e.getChannel().write(partialresponse);
        return future;
        }
}
Was it helpful?

Solution

First of you should share one instance of HashedWheelTimer between your pipelines, as it will create one thread per instance. But now to your problem..

If you use a IdleStateHandler you also need to implement an IdleStateAwareHandler or IdleStateAwareChannelUpstreamHandler which will react on the IdleState events which get triggered by the IdleStateHandler. So if you want for example to disconnect the Channel after it was idle for you could just call Channel.close() on it after receiving the event.

See also:

http://netty.io/docs/stable/api/org/jboss/netty/handler/timeout/IdleStateAwareChannelUpstreamHandler.html

Another solution would be to add the ReadTimeoutHandler and then act on the ReadTimeoutException when you caught it in the exceptionCaught(..) method.

See: http://netty.io/docs/stable/api/org/jboss/netty/handler/timeout/ReadTimeoutHandler.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top