2012-11-26 45 views
0

如何在基於Netty的TCP服務器中實現@SessionScoped?在Guice手冊中記錄了創建Custom Scopes,但似乎該解決方案僅適用於基於線程而不是異步IO服務器。在Netty中使用Guice的@SessionScoped

是否足以創建渠道管道scope.enter()scope.exit()之間?

+0

是否Netty的支持 「會話中的對象」?它看起來像Channel.getId()是Netty一樣。因此,您可以使用[示例](http://code.google.com/p/google-guice/wiki/CustomScopes)並將ThreadLocal切換爲,Object >>的映射。 –

回答

1

聲明:此答案適用於Netty 3.我還沒有機會嘗試Netty 4,因此我不知道以下內容是否適用於較新的版本。

Netty在網絡端是異步的,但除非您明確地向Executors提交任務或通過任何其他方式更改線程,否則管道上的ChannelHandlers的處理是同步且順序的。例如,如果您使用Netty 3並在管道上有ExecutionHandler,則作用域處理程序應位於ExecutionHandler的上游;對於Netty 4,請參閱Trustin Lee的評論。

因此,你可以把一個處理器附近的管道管理會話範圍開始,例如:

public class ScopeHandler implements ChannelUpstreamHandler { 

    @Override 
    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) { 

     if (e instanceof WriteCompletionEvent || e instanceof ExceptionEvent) 
      ctx.sendUpstream(e); 

     Session session = ...; // get session, presumably using e.getChannel() 

     scope.enter(); 
     try { 
      scope.seed(Key.get(Session.class), session); 
      ctx.sendUpstream(e); 
     } 
     finally { 
      scope.exit(); 
     } 
    } 

    private SessionScope scope; 

} 

一對夫婦快速的言論:

  • 你想過濾一些事件類型,特別是WriteCompletionEventExceptionEvent,框架將在事件處理期間放置在管道的下游端,並且如果不排除則會導致重入問題。在我們的應用程序中,我們使用這種處理程序,但實際上只考慮UpstreamMessageEvent s。
  • 由於Netty會捕獲任何Throwable並觸發ExceptionEvent,所以try/finally構造實際上並不是必需的,但這樣感覺更具慣用性。

HTH

+0

您是否使用自己的擴展SimpleScope的SessionScope? – jkj

+0

@jkj是的,這就是我的例子所假設的。 –

+0

不錯的作品@ThomasDufour!這個想法也應該適用於Netty 4.但是,如果用戶在設置管道時爲處理程序指定了「EventExecutor」,則必須再次設置範圍,因爲該事件將切換到另一個線程。 (就像Netty 3中的ExecutionHandler一樣)。 – trustin