0

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

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

4

1 回答 1

1

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

Netty 在网络端是异步的,但除非你明确地向 Executors 提交任务,或者通过任何其他方式更改线程,否则管道上 s 对ChannelEvents的处理是同步和顺序的。ChannelHandler例如,如果你使用 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,但这种方式感觉更惯用。

高温高压

于 2012-11-29T14:19:23.770 回答