Dependency injection 使用Guice';s@Sessions与Netty合作

Dependency injection 使用Guice';s@Sessions与Netty合作,dependency-injection,guice,netty,Dependency Injection,Guice,Netty,如何在基于Netty的TCP服务器中实现@SessionScoped?Guice手册中记录了创建,但该解决方案似乎只适用于基于线程的IO服务器,而不适用于异步IO服务器 在scope.enter()和scope.exit()之间创建通道管道是否足够?免责声明:此答案适用于Netty 3。我还没有机会尝试Netty 4,所以我不知道下面的内容是否适用于新版本 Netty在网络端是异步的,但除非您明确地将任务提交给执行者,或者通过任何其他方式更改线程,否则管道上的ChannelHandlers对Ch

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


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

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

Netty在网络端是异步的,但除非您明确地将任务提交给执行者,或者通过任何其他方式更改线程,否则管道上的
ChannelHandler
s对
ChannelEvent
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;

}
下面是几句简短的评论:

  • 您需要过滤掉一些事件类型,特别是
    WriteCompletionEvent
    ExceptionEvent
    ,框架将在事件处理期间将其放置在管道的下游端,如果不排除这些事件,将导致重入问题。在我们的应用程序中,我们使用这种处理程序,但实际上只考虑<代码>上行链路事件> <代码> S.
  • try/finally构造实际上并不是必需的,因为Netty将捕获任何
    可丢弃的
    s并触发一个异常事件,但这样感觉更为惯用

HTH

Netty是否支持“会话对象”?它看起来和Channel.getId()很像。因此,您可以使用和切换ThreadLocal out来创建一个映射,您是否使用自己的SessionScope来扩展SimpleScope?@jkj是的,这就是我的示例所假设的。干得好@ThomasDufour!这个想法也适用于Netty 4。但是,如果用户在设置管道时为处理程序指定了一个
EventExecutor
,则必须重新设置作用域,因为事件将被传递到不同的线程。(就像Netty 3中的
ExecutionHandler
一样。)谢谢@TrustinLee,我编辑了答案,在Netty 3中提到了
ExecutionHandler