728x90
앞에서 봤던 Decoder에 이어서 Encoder에 대해 알아보자
Decoder는 InBound로, Encoder는 Outbound에 쓰인다.
2022.01.07 - [프로그래밍/Netty Encoder & Decoder] - Netty Decoder with VS Code (2)
앞의 예제를 보면 마지막 오류난 코드를 보자
MyChannelHandler의 readChannel에 보면 writeAndFlush에서 Integer를 그대로 보냈다.
그러다 보니 읽는 쪽에(channel.readOutbound)에서는 Integer로 읽어야 하는데 ByteBuf로 읽으니 오류가 난것이다.
그럼 보낼때 ByteBuf로 보내면 되니 그렇게 Encoder를 작성 해보자
public class ChannelTest {
private final Logger logger = LoggerFactory.getLogger(ChannelTest.class); // logger달고
@Test
public void DecoderTest() {
EmbeddedChannel channel = new EmbeddedChannel();
channel.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
channel.pipeline().addLast(new MyDecoder());
channel.pipeline().addLast(new MyChannelHandler());
ByteBuf inBuf = (ByteBuf)Unpooled.buffer(4);
inBuf.writeInt(-10);
channel.writeInbound(inBuf);
ByteBuf readBuf = channel.readOutbound();
logger.info("readBuf = {}", readBuf.readInt());
channel.finish(); // 쓰기종료
}
}
class MyChannelHandler extends ChannelInboundHandlerAdapter {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("Read .. {}", (Integer) msg);
ctx.channel().writeAndFlush(msg); // (1) Integer를 그대로 씀
}
}
ByteBuf로 쓰는 Encoder를 만들어보자
MessageToByteEncoder<Integer>를 상속받아서 만들자.
encode 함수는 재정의 하고, Decoder와 마찬가지로 Integer 타입의 메시지를 받아서 ByteBuf output에 쓴다.
class MyEncoder extends MessageToByteEncoder<Integer> {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
protected void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out) throws Exception {
logger.info("encoder..{}",msg);
out.writeInt(msg);
}
}
BytBuf의 writeInt를 보면 int 값을 받아서 ByteBuf로 돌려준다.
여기 설명에서 보면 writeIndex가 나오는데, 이건 추후에 다시 둘러보자
다시 수정해서 돌려보자
pipeline에 MyEncoder를 추가하고, read.Outbound()에서 형변환을 빼고 수행해보면 정상 동작한다.
import java.util.List;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class ChannelTest {
private final Logger logger = LoggerFactory.getLogger(ChannelTest.class); // logger달고
@Test
public void DecoderTest() {
EmbeddedChannel channel = new EmbeddedChannel();
channel.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
channel.pipeline().addLast(new MyDecoder());
channel.pipeline().addLast(new MyChannelHandler());
channel.pipeline().addLast(new MyEncoder()); // writeInt Encoder추가
ByteBuf inBuf = (ByteBuf)Unpooled.buffer(4);
inBuf.writeInt(-10);
channel.writeInbound(inBuf);
ByteBuf readBuf = channel.readOutbound(); //형변환 제거
logger.info("readBuf = {}", readBuf.readInt()); //
channel.finish(); // 쓰기종료
}
}
class MyChannelInitializer extends ChannelInitializer<Channel> {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
protected void initChannel(Channel ch) throws Exception {
logger.info("init Channel.. ");
ch.pipeline().addLast(new LoggingHandler(LogLevel.INFO));
}
}
class MyDecoder extends ByteToMessageDecoder {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
logger.info("decode start.. {}", in.getInt(0));
out.add(Math.abs(in.readInt()));
logger.info("decode end.. ");
}
}
//Encoder 추가
class MyEncoder extends MessageToByteEncoder<Integer> {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
protected void encode(ChannelHandlerContext ctx, Integer msg, ByteBuf out) throws Exception {
logger.info("encoder..{}",msg);
out.writeInt(msg);
}
}
class MyChannelHandler extends ChannelInboundHandlerAdapter {
private final Logger logger = LoggerFactory.getLogger(App.class); // logger달고
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
logger.info("Read .. {}", (Integer) msg);
ctx.channel().writeAndFlush(msg);
}
}
728x90
'프로그래밍 > Netty Encoder & Decoder' 카테고리의 다른 글
Netty Encoder & Decoder (0) | 2022.01.10 |
---|---|
Netty Decoder with VSCode (2) (0) | 2022.01.07 |
Netty Encoder with VSCode (0) | 2022.01.06 |
Netty Decoder with VS Code (1) (0) | 2022.01.06 |