使用Guice的@SessionScoped和Netty

时间:2012-11-26 13:18:40

标签: dependency-injection guice netty

如何在基于Netty的TCP服务器中实现@SessionScoped? Guice手册中记录了创建Custom Scopes,但似乎该解决方案仅适用于基于线程的而非异步IO服务器。

scope.enter()scope.exit()之间创建频道管道是否足够?

1 个答案:

答案 0 :(得分:1)

免责声明:这个答案适用于Netty 3.我还没有机会尝试使用Netty 4,所以我不知道以下内容是否适用于新版本。

Netty在网络端是异步的,但除非你明确地向Executors提交任务,或者通过任何其他方式更改线程,否则管道上ChannelEventChannelHandler s的处理是同步的和顺序。例如,如果您使用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。
  • try / finally结构实际上并不是必需的,因为Netty将捕获任何Throwable并触发ExceptionEvent,但这种方式感觉更加惯用。

HTH