Netty Comet Async request time out

折月煮酒 提交于 2019-12-23 02:19:00

问题


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;
        }
}

回答1:


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



来源:https://stackoverflow.com/questions/8873825/netty-comet-async-request-time-out

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!