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이름 클릭하면 상세 내용으로도 넘어간다
여기서 보면 이벤트들이 보인다. 해당 Method에는 전부 ChannelHandlerContext 와 ChannelRead는 특별하게 Object msg 가 추가로 있다. 뭐 설명 안해도 알겠지만 여기에 받은 메시지가 있겠지?
직접돌려보자
여기서 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
다음장에서 channel의 이벤트들에 대해 조금 더 알아보자
'프로그래밍 > 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 |