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