NettyベースのTCPサーバーに@SessionScopedを実装するにはどうすればよいですか?カスタムスコープの作成はGuiceマニュアルに記載されていますが、ソリューションはスレッドベースでのみ機能し、非同期IOサーバーでは機能しないようです。
との間にチャネルパイプラインを作成するだけで十分ですか?scope.enter()
scope.exit()
NettyベースのTCPサーバーに@SessionScopedを実装するにはどうすればよいですか?カスタムスコープの作成はGuiceマニュアルに記載されていますが、ソリューションはスレッドベースでのみ機能し、非同期IOサーバーでは機能しないようです。
との間にチャネルパイプラインを作成するだけで十分ですか?scope.enter()
scope.exit()
免責事項:この回答はNetty 3に対するものです。私はまだNetty4を試す機会がなかったので、次の内容を新しいバージョンに適用できるかどうかわかりません。
Nettyはネットワーク側では非同期ですが、エグゼキュータにタスクを明示的に送信するか、他の方法でスレッドを変更しない限り、パイプライン上ChannelEvent
のsによるsの処理ChannelHandler
は同期的かつ順次的です。たとえば、Netty 3を使用していExecutionHandler
て、パイプライン上にある場合、スコープハンドラーはExecutionHandler
;の上流にある必要があります。Netty 4については、TrustinLeeのコメントを参照してください。
したがって、セッションスコープを管理するハンドラーをパイプラインの先頭近くに配置できます。次に例を示します。
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のみを考慮しUpstreamMessageEvent
ます。Throwable
NettyはすべてのsをキャッチしてExceptionEventを発生させるため、try / final構文は実際には必要ありませんが、この方法ではより慣用的に感じられます。HTH