[ネティ開始]8ガイドテープ


8.ガイドバー


ブートストラップは、アプリケーションを実行するように構成するプロセスです.特に、ネットワークアプリケーションでは、定義ほど簡単な手順ではありません.
アプリケーションがクライアントであれサーバであれ、アプリケーションをネットワーク・レイヤから分離することをサポートします.すぐに、すべてのフレームワークコンポーネントがバックグラウンドで接続され、アクティブになります.
起動バーは、私たちがこれまで組み立てたパズルの残りの破片で、これらの破片を元の場所に戻すと、アプリケーションが完了します.

ブートストラップクラス


ネティのガイドバークラス階層は、抽象的な親クラスと2つの構想ガイドバーサブクラスから構成されます.
サーバは、親チャネルがクライアントから受信および通信接続されるためにサブチャネルを作成しますが、クライアントは通常、親チャネルではなくすべてのネットワークインタラクションを行うチャネルを必要とします.

非接続プロトコルとクライアント・ブート・バー


Bootstrapは、非接続プロトコルを使用するアプリケーションまたはクライアントに使用されます.

クライアントガイド


クライアントガイド
EventLoopGroup group = new NioEventLoopGroupo();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
    .channel(NioSocketChannel.class)
    .handle(new SimpleChannelInboundHandler<ByteBuf>() {
        @Override
        public void channelRead0(
            ChannelHandlerContext channelHandlerContext,
            ByteBuf byteBUf) throws Exception {
                System.out.println("Received data");
            }
        )
    });
ChannelFuture future = bootstrap.connect(new InetSocketAddress("www.maiiing.com", 80));
future.addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture channelFuture) throws Exception 
    {
        if (channelFuture.isSuccess()) {
            System.out.println("Connection established");
        }
        else {
            System.err.println("Conenction failed");
            channelFuture.cause().printStackTrace();
        }
    }
});

### Channel과 EventLoopGroup의 호환성

NioEventLoopGroup 및 OioSocketChannel과 같은 서로 다른 접두사를 가진 컴포넌트를 혼합할 수 없다.

## 서버 부트스트랩

ServerBootstrap 클래스에는 Bootstrap클래스에는 없는 childHandler(), childAttr(), childOption()메서드가 있다.
이러한 메서드는 서버 애플리케이션에서 자주 이용되는 작업을 지원한다.
ServerChannel 구현은 수락된 연결을 나타내는 자식 Channel을 생성한느 역할을 한다.
즉, ServerChanel을 부트스트랩하는 ServerBootstrap은 수락된 Channel의 ChannelConfig 멤버에 설정을 적용하는 과정을 간소화하는 이러한 메서드를 제공한다.

NioEventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(group)
    .channel(NioServerSocketChannel.class)
    .childHandler(new SimpleChannelInboundHandler<ByteBuf>() {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
            System.out.println("Received data");
        }
    });
    ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
    future.addListener(new ChannelFutureListener() {
        @Override 
        public void operationComplete(ChannelFuture channelFuture) {
            if (channelFuture.isSuccess()) {
                System.out.println("Server bound");
            }
            else {
                channelFuture.cause().printStackTrace();
            }
        }
    });

チャネル内のクライアントガイド


サーバが別の3次フェースシステムのクライアント要求を処理すると仮定し、この要求はクライアントとして実行する必要があります.このような状況は、プロキシ・サーバなどのアプリケーションを既存のエンタープライズ・システム(Webサービスやデータベースなど)に統合する必要がある場合に発生します.この場合、サーバチャネルからクライアントチャネルを起動する必要があります.
サーバーのブートストラップ
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
    .channel(NioServerSocketChannel.class)
    .childHandler(
            new SimpleChannelInboundHandler<ByteBuf>() {
                ChannelFuture connectFuture;
                @Override
                public void channelActive(ChannelHandlerCOntext ctx)
                {
                    Bootstrap bootstrap = new Bootstrap();
                    bootstrap.channel(NioSocketChannel.class).handler(
                        new SimpleChannelInboundHandler<ByteBuf>() {
                            @Override
                            protected void channelRead0(
                                ChannelHandlerContext ctx, ByteBuf in
                            ) throws Exception {
                                System.out.println("Received data");
                            }
                        }
                    );

                    @Override
                    protected void channelRead0(
                        ChannelHandlerContext ctx, ByteBuf in
                    ) throws Exception {
                        if (connectionFuture.isDone()) {
                            //데이터를 이용해 필요한 일을 함.
                        }                    
                    }
                }

            }
    );
    
    ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
    future.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture channelFuture) throws Exception
        {
            if (channelFuture.isSuccess()) {
                System.out.println("Server bound");
            }
            else {
                System.err.println("Bind attempt failed");
            }
        }
    });
~~

の最後の部分


ブートストラップはアプリケーションを起動するプロセスですが、最終的にはアプリケーションを正常に閉じる必要があります.もちろん、JVMはアプリケーションを終了するときにすべてのタスクに代わることができますが、リソースのクリーンアップを意味するため、通常の終了とは言えません.アプリケーションを閉じるには、あまり複雑なテクノロジーは必要ありませんが、いくつかの点を考慮する必要があります.
最も重要なのは、EventLoopGroupを終了し、待機しているすべてのイベントとタスクを処理し、すべてのアクティブなスレッドを無効にする必要があります.そのため、EventLoopGroup.終了時に通知を受信したFutureを返すsuttdownGraceful()を呼び出す必要があります.「閉鎖自守」()は非同期で働いているので、テナントを登録し、完了する前に進捗を阻止したり、テナントを登録して戻ったFUTUREで完了通知を受信したりしなければなりません.
正常に閉じる
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
    .channel(NioSocketChannel.class);

...
Future<?> future = group.shutdownGracefully();

future.syncUninterruptibly();