2012-01-15 46 views
1

我試圖使用Jboss Netty創建長輪詢Comet。Netty Comet異步請求超時

如何配置30秒的時間?繼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; 

,但它不工作,我的要求是永恆的。這怎麼解決?

是否意味着我需要執行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); 
     } 

} 

和內部可贖回的,我只是監控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

首先應該分享您的管道之間HashedWheelTimer的一個實例,因爲它會創建一個線程每個實例。但現在到您的問題..

如果您使用IdleStateHandler您還需要實現IdleStateAwareHandler或IdleStateAwareChannelUpstreamHandler將對由IdleStateHandler觸發的IdleState事件作出反應。因此,如果您希望在閒置後斷開通道的連接,您可以在接收事件後調用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

+0

這很好謝謝。我正在使用Async Comet,並且每個監視BlockedQueue 的通道都有Thread,我的問題是IdleStateAwareChannelUpstreamHandler不會停止線程工作。 – 2012-01-16 16:33:37

+0

對不起,我沒有得到它......即使你使用每個通道的一個線程,它不是一個好主意「不」共享HashedWheelTimer,因爲它帶有一些開銷。如果你需要從空閒處理中取消你的線程,你將需要提供一個方法待辦事項。但那更多的東西在你的代碼範圍內然後在netty中。我仍然認爲你應該避免每個通道使用一個線程.... – 2012-01-17 10:40:46

+0

你能告訴我你是什麼意思的「每個通道線程」?如果我正在運行Callable = new Callable(Channel),並且正在監視BlockedQueue ,我是否在每個通道使用線程? – 2012-01-17 10:57:30