如何在基于Netty的TCP服务器中实现@SessionScoped? Guice手册中记录了创建Custom Scopes,但似乎该解决方案仅适用于基于线程的而非异步IO服务器。
在scope.enter()
和scope.exit()
之间创建频道管道是否足够?
答案 0 :(得分:1)
免责声明:这个答案适用于Netty 3.我还没有机会尝试使用Netty 4,所以我不知道以下内容是否适用于新版本。
Netty在网络端是异步的,但除非你明确地向Executors提交任务,或者通过任何其他方式更改线程,否则管道上ChannelEvent
对ChannelHandler
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
,框架将在事件处理期间放置在管道的下游端,如果不排除,将导致重入问题。在我们的应用程序中,我们使用这种处理程序,但实际上只考虑UpstreamMessageEvent
s。Throwable
并触发ExceptionEvent,但这种方式感觉更加惯用。HTH