0

NettyベースのTCPサーバーに@SessionScopedを実装するにはどうすればよいですか?カスタムスコープの作成はGuiceマニュアルに記載されていますが、ソリューションはスレッドベースでのみ機能し、非同期IOサーバーでは機能しないようです。

との間にチャネルパイプラインを作成するだけで十分ですか?scope.enter()scope.exit()

4

1 に答える 1

1

免責事項:この回答は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ます。
  • ThrowableNettyはすべてのsをキャッチしてExceptionEventを発生させるため、try / final構文は実際には必要ありませんが、この方法ではより慣用的に感じられます。

HTH

于 2012-11-29T14:19:23.770 に答える