Skip to content

네티의 비동기 I O 처리

andy edited this page Sep 16, 2019 · 4 revisions

비동기 호출을 위해 네티는 두 가지 패턴을 제공

리액터 패턴

이벤트 핸들러는 리액터 패턴의 구현체

참고: https://unagi44.wordpress.com/2015/12/02/reactor-pattern/

퓨처 패턴

  • 미래에 완료될 작업을 등록하고 처리 결과를 확인하는 객체를 통해서 작업의 완료를 확인하는 패턴

  • 메서드를 호출하는 즉시 퓨처 객체를 반환

  • 예제코드

    Bakery bakery = new Bakery();
    
    // 케이크를 주문하고 주문서를 받는다.
    Future future = bakery.orderCake();
    
    // 다른 일을 한다.
    doSomething();
      
    // 케이크가 완성되었는지 확인한다.
    if(future.isDone()) {
      Cake cake = future.getCake();
    } else {
      // 케이크가 완성되었는지 확인한다.
      while(future.isDone() != true) {
        // 다른 일을 한다.
        doSomething();
      }
      
      // while 루프를 빠져나왔으므로 완성된 케이크를 가져온다.
      Cake cake = future.getCake();
    }
  • 에코 서버 main 코드

    ChannelFuture bindFutre = b.bind(8888);
    bindFuture.sync();
    Channel serverChannel = bindFuture.channel();
    ChannelFuture closeFuture = serverChannel.closeFuture();
    closeFuture.sync();
    1. 에코 서버가 8888번 포트를 사용하도록 바인드하는 비동기 bind 메서드를 호출
      포트 바인딩이 완료되기 전에 ChannelFuture객체를 반환
    2. ChannelFuture 객체의 작업이 완료될 때까지 블로킹
    3. bindFuture 객체를 통해서 채널(888번 포트에 바인딩된 서버 채널)을 얻어 옴
    4. 바인드가 완료된 서버 채널의 CloseFuture 객체를 반환 (네티 내부에서는 채널이 생성될 때 CloseFuture 객체도 같이 생성되므로 반환되는 객체는 항상 동일)
    5. CloseFuture 객체는 채널의 연결이 종료될 때 연결 종료 이벤트를 받음
  • 채널 리스너 설정

    public class EchoServerV2Handler extends ChannelInboundHandlerAdapter {
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ChannelFuture channelFuture = ctx.writeAndFlush(msg);
            channelFuture.addListener(ChannelFutureListener.CLOSE);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }
    ChannelFutureListener Description
    CLOSE ChannelFuture 객체가 작업 완료 이벤트를 수신했을 때 ChannelFuture 객체에 포함된 채널을 닫는다.
    CLOSE_ON_FAILURE ChannelFuture 객체가 완료 이벤트를 수신하고 결과가 실패일 때 ChannelFuture 객체에 포함된 채널을 닫는다.
    FIRE_EXCEPTION_ON_FAILURE ChannelFuture 객체가 완료 이벤트를 수신하고 결과가 실패일 때 채널 예외 이벤트를 발생시킨다.

    참고: https://alvinalexander.com/java/jwarehouse/netty-4.1/transport/src/main/java/io/netty/channel/ChannelFutureListener.java.shtml