본문 바로가기
프로그래밍/Netty 기초

04. ChannelHandler 란

by Flow.X 2022. 1. 6.
728x90

ChannelHandler는  편의점에 손님이 들어왔을때 어떻게 응대할까?를 정의하는 것이라고 생각하면 쉬울 듯 하다.

 

즉, 어린 친구가 편의점에 왔을 때 눈높이를 낮추고 조곤조곤 이야기하고, 진상 손님이 오면 대응하는게 달라지 듯이 나름대로의

메뉴얼을 머릿속으로 가지고 있듯 여기서 나름대로의 메뉴얼을 만들 수 있을것 같다 

 

ChannelHandler의 종류

ChannelHandler는 들어온 이벤트를 처리하는 ChannelInboundHandler와  나가는 이벤트를  처리하는 ChannelOutboundHandler가 있고,  ChannelDuplexHandler는 나가는것과 들어오는것 이벤트를 두개다 처리하는 핸들러가 있다.

 

ChannelHandler를 정의하자 

하단 코드에서 p.addLast(new DiscardServerHandler()); 를 추가해서 손님이 들어왔을때 어떻게 할지 처리를 하는걸

넣었다

b.childHandler(new ChannelInitializer<SocketChannel>() { // 첫고객이 문열고 들어왔을때 어떻게 할까 결정(고객응대방법)
	@Override
	public void initChannel(SocketChannel ch) {
		ChannelPipeline p = ch.pipeline();
		p.addLast(new DiscardServerHandler());
	}
});

 

DiscardServerHandler를 보자

해당 클래스는 ChannelInboundHandlerAdapter 를 extends(상속) 했다. 

  • 이렇게 하면 부모의 메소드를 그대로 사용할 수 있으며 오버라이딩 할 필요 없이 부모에 구현되있는 것을 직접 사용 가능하다.

그럼 저 부모를 봐야 뭘 쓸수 있는지 알수 있겠지

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class DiscardServerHandler extends ChannelInboundHandlerAdapter {

}

ChannelInboundHandler

intellisense 기능을 확인해봐도 되고 Visual Studio Code에서  cmd + java이름 클릭하면 상세 내용으로도 넘어간다 

ChannelInboundHandler 내 무엇이 있을까?
상세내역보기

여기서 보면 이벤트들이 보인다. 해당 Method에는  전부 ChannelHandlerContext 와  ChannelRead는 특별하게 Object msg 가 추가로 있다.  뭐 설명 안해도 알겠지만 여기에 받은 메시지가 있겠지?

ChannelInboundAdapter method

 

직접돌려보자 

 

여기서 log4j 2설정이 추가되었는데, 이건 어떻게 설정하는지 아래서 확인하자.

2021.12.24 - [Netty/Log4J 설정] - Log4J2 설정

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class DiscardServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LogManager.getLogger(DiscardServerHandler.class.getName());

    public DiscardServerHandler() {
        Configurator.setLevel(DiscardServerHandler.class.getName(), Level.ALL);
        logger.info("DiscardServerHandler init..");
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        logger.info("channelRegistered..");
        ctx.fireChannelRegistered();
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelUnregistered();
        logger.info("channelUnregistered..");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelActive();
        logger.info("channelActive..");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelInactive();
        logger.info("channelInactive..");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.fireChannelRead(msg);
        logger.info("channelRead..");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelReadComplete();
        logger.info("channelReadComplete..");
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        ctx.fireUserEventTriggered(evt);
        logger.info("userEventTriggered..");
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        ctx.fireChannelWritabilityChanged();
        logger.info("channelWritabilityChanged..");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.fireExceptionCaught(cause);
        logger.info("exceptionCaught..");
    }

}

이벤트 처리 순서를 보자 

상상했던대로 흘러가는걸 볼수 있을 것이다.

 

처음 접속했을때 흐름  : handler Init ▶ channelRegistered ▶ channelActive 

데이터가 왔을때 흐름 : channelRead ▶ channelReadComplete

접속을 끊었을때 흐름 : channelInactive ▶ channelUnregistered

channelInboundAdapter 이벤트 흐름

다음장에서 channel의 이벤트들에 대해 조금 더 알아보자

 

 

728x90

'프로그래밍 > Netty 기초' 카테고리의 다른 글

06. Discard Client 만들기  (0) 2022.01.07
05. channeInboundAdapter 이벤트 순서  (0) 2022.01.06
03. Discard 서버로 기초를 만들어보자  (0) 2022.01.06
01. Netty란  (0) 2022.01.06
02. Discard 서버  (0) 2022.01.06