앞에서 말했던 pipeline을 좀더 조작해보자
여기서 해볼꺼는 ByteBuf 로 받는거를 String으로 변환하는 Codec을 추가해서 귀찮은 형변환을 간단하게 해보고
엔터키가 오면 그걸 잘라서 처리해보고자 한다.
데이터를 받을때 ByteBuf로 기본으로 받다보니 변환해서 사용해야했다
우선 CodeSampleHandler.java의 channelRead 코드를 보면
Object msg -> ByteBuf -> String으로 변환한 뒤 사용했다.
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String strRecv = ((ByteBuf) msg).toString(CharsetUtil.UTF_8);
logger.info("channelRead.. READ : {}", strRecv);
String strReturn = ">> " + strRecv;
ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(strReturn.length()); // 필요한 길이만큼 할당
buf.writeBytes(strReturn.getBytes(CharsetUtil.UTF_8)); // 얻어온 ByteBuf에 쓰기
ctx.channel().writeAndFlush(buf); // 보내기
}
디버깅을 해보면 msg 이놈이 ByteBuf로 온다.
String으로 받으면 좀 편할텐데..
Codec을 추가해보자.
LoggingHandler (ByteBuf) ▶ StringDecoder (string) ▶ CodeSamplerHandler (String) ▶ StringEncoder (ByteBuf)
로 쭉 흘러간다. 괄호 안은 어떻게 데이터가 형변환 되어 있는지 보여준다
CodecSample.java 수정
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// 손님 들어왔을때 대응메뉴얼
logger.info("손님 문열고 들어옵니다..");
ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new CodecSampleHandler());
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
}
});
CodeSampleHandler.java 수정
msg를 String으로 변환해서 이제 바로 쓸수 있다
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String strRecv = (String) msg; // String으로 변환
logger.info("channelRead.. READ : {}", strRecv);
String strReturn = ">> " + strRecv;
ctx.channel().writeAndFlush(strReturn); // 보내기
}
디버깅 해서 보면 String으로 표시된다.
Hi 뒤에 보면 뭔가 또 달려있는게 보인다. 저걸 없애보자.
손님이 와서 주문을 하는데 주문이 끝날때는 카드를 내밀어야 한다. 주문이 끝나기도 전에 카드를 내밀면 무조건 결제하고, 추가주문을
받는다는 원칙을 세웠다고 하자.
그럼 고객은 항상 주문이 완료되면 카드를 내밀것이다. 그걸 캐치해서 다음 단계로 진행시키고, 이후 다시 주문받고 하면 되겠다.
ChannelHandler 중 Netty 샘플에서 가장많이 쓰는것이 아래 두개이다
LineBasedFrameDecoder : 라인단위로 가져와서 처리
LengthFieldBasedFrameDecoder : 앞에다가 내가 보낼 사이즈는 얼마야 라고 먼저 보내고 이야기를 하는것
그 중 LineBasedFrameDecoder 를 써보자
우선 설명을 보면 받은 ByteBuf를 \n, \r\n으로 나눈다고 한다
함수에 커서를 두고 cmd + . (맥기준) 을 누르면 아래와 같이 설명이 나온다.
여기서 설명을 보면 최대길이를 지정하라고 되어 있네..
CodeSample에 추가한 모습이다.
이제는 이렇게 흘러간다
LoggingHandler ▶ LineBasedFrameDecoder ▶ StringDecoder ▶ CodeSamplerHandler ▶ StringEncoder
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// 손님 들어왔을때 대응메뉴얼
logger.info("손님 문열고 들어옵니다..");
ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
ch.pipeline().addLast(new LineBasedFrameDecoder(10));
ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8));
ch.pipeline().addLast(new CodecSampleHandler());
ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
}
});
실행해보자. 깔끔하게 짤렷다.
추가 안했을때 모습을 다시보자. 뒤에 뭔가가 붙어있다.
앞에서 maxlength를 10으로 했는데 만약 오버하면 어떻게 될까?
아래처럼 오류가 나고, 다음 코드는 아에 수행이 안된다.
기본적으로 손님이 왔을때 진상이면 거부도 할수 있겠구나 싶다.
'프로그래밍 > Netty Codec 이해하기' 카테고리의 다른 글
Netty Pipeline 및 Codec 활용(4) (0) | 2022.01.10 |
---|---|
Netty Pipeline 및 Codec 활용(1) (0) | 2022.01.10 |
Netty Pipeline 및 Codec 활용(3) (0) | 2022.01.10 |