【问题标题】:Using Guice's @SessionScoped with Netty使用 Guice 的 @SessionScoped 和 Netty
【发布时间】:2012-12-04 00:50:01
【问题描述】:

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

scope.enter()scope.exit() 之间创建Channel Pipeline 是否足够?

【问题讨论】:

  • Netty 支持“会话对象”吗?看起来 Channel.getId() 与 Netty 相似。因此,您可以使用example 并将 ThreadLocal 切换为 , Object>> 的映射。

标签: dependency-injection guice netty


【解决方案1】:

免责声明:这个答案是针对Netty 3的。我还没有机会尝试Netty 4,所以我不知道下面的内容是否可以应用于较新的版本。

Netty 在网络端是异步的,但除非你明确地向 Executors 提交任务,或者通过任何其他方式更改线程,否则管道上 ChannelHandlers 对 ChannelEvents 的处理是同步和顺序的。例如,如果您使用 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,框架将在事件处理期间将它们放在管道的下游端,如果不排除它们会导致重入问题。在我们的应用程序中,我们使用了这种处理程序,但实际上只考虑了UpstreamMessageEvents。
  • try/finally 构造实际上不是必需的,因为 Netty 会捕获任何 Throwables 并触发 ExceptionEvent,但这种方式感觉更惯用。

HTH

【讨论】:

  • 您是否使用自己的扩展 SimpleScope 的 SessionScope?
  • @jkj 是的,这就是我的示例所假设的。
  • 干得好@ThomasDufour!这个想法也应该适用于 Netty 4。但是,如果用户在设置管道时为处理程序指定 EventExecutor,则必须再次设置范围,因为该事件将被移交给不同的线程。 (就像 Netty 3 中的 ExecutionHandler 一样。)
  • 感谢@TrustinLee,我已经编辑了在Netty 3案例中提到ExecutionHandler的答案。
猜你喜欢
  • 2013-11-07
  • 2011-08-12
  • 1970-01-01
  • 2014-08-02
  • 2013-12-11
  • 1970-01-01
  • 2011-06-21
  • 2011-03-23
  • 2017-08-04
相关资源
最近更新 更多