Netty Comet Async время ожидания запроса - PullRequest
1 голос
/ 16 января 2012

Я пытаюсь создать длинную опрашивающую комету с помощью Jboss Netty.

Как настроить время из 30 секунд?После документа:

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

, но это не работает, и моя просьба длится вечно.Как это можно решить?

Означает ли это, что мне нужно реализовать Callable<T>, затем вызвать Future.get с параметром тайм-аута и завершить запрос, если TimeOutException произойдет?Тогда я должен использовать Future<ChannelFuture>?

Есть ли другой подход?

Код:

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

}

и внутри Callable я просто отслеживаю 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 Ответ

1 голос
/ 16 января 2012

Прежде всего вы должны совместно использовать один экземпляр HashedWheelTimer между вашими конвейерами, поскольку он будет создавать один поток на экземпляр.Но теперь к вашей проблеме ..

Если вы используете IdleStateHandler, вам также необходимо реализовать IdleStateAwareHandler или IdleStateAwareChannelUpstreamHandler, который будет реагировать на события IdleState, которые запускаются IdleStateHandler.Поэтому, если вы хотите, например, отключить канал после простоя, вы можете просто вызвать Channel.close () для него после получения события.

См. Также:

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

Другим решением было бы добавить ReadTimeoutHandler, а затем воздействовать на исключение ReadTimeoutException, когда вы перехватили его в методе exceptionCaught (..).

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

...