Dependency injection 使用Guice';s@Sessions与Netty合作
如何在基于Netty的TCP服务器中实现@SessionScoped?Guice手册中记录了创建,但该解决方案似乎只适用于基于线程的IO服务器,而不适用于异步IO服务器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
在
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
,框架将在事件处理期间将其放置在管道的下游端,如果不排除这些事件,将导致重入问题。在我们的应用程序中,我们使用这种处理程序,但实际上只考虑<代码>上行链路事件> <代码> S.ExceptionEvent
- try/finally构造实际上并不是必需的,因为Netty将捕获任何
s并触发一个异常事件,但这样感觉更为惯用可丢弃的
HTHNetty是否支持“会话对象”?它看起来和Channel.getId()很像。因此,您可以使用和切换ThreadLocal out来创建一个映射,您是否使用自己的SessionScope来扩展SimpleScope?@jkj是的,这就是我的示例所假设的。干得好@ThomasDufour!这个想法也适用于Netty 4。但是,如果用户在设置管道时为处理程序指定了一个
EventExecutor
,则必须重新设置作用域,因为事件将被传递到不同的线程。(就像Netty 3中的ExecutionHandler
一样。)谢谢@TrustinLee,我编辑了答案,在Netty 3中提到了ExecutionHandler
。