kcb와의 통신을 위해서 netty를 처음 사용해 보았다.
좌충우돌이 많았지만 무사히 잘 마무리가 되었다.
서버에서 euc-kr을 사용해서 그와 관련된 처리 부분에서 시간을 많이 허비했다.
한글을 바이트 단위로 쪼개는 게 평소에는 잘하지 않는 부분이라 시간이 걸렸다.
별거 없는 내용이지만 이렇게 적어 두지 않으면 나중에 또 시간을 허비할게 뻔해서 최대한 틀만 살려서 내용을 기록해 둔다.
혹시나 netty를 사용하실 분에 도움이 되었으면 좋겠다.
import java.io.UnsupportedEncodingException;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import lombok.extern.slf4j.Slf4j;
public class TestService {
public static final String ENCODING = "EUC-KR";
public static final Charset ENCODE = Charset.forName(ENCODING);
//네티 세팅
public void runApi() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, "5000")
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder(ENCODE));
pipeline.addLast(new StringEncoder(ENCODE));
pipeline.addLast(new NettyClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect(new InetSocketAddress("host", "port")).sync();
NettyClientHandler clientHandler = (NettyClientHandler) channelFuture.channel().pipeline().last();
clientHandler.init(this);
channelFuture.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
// 서버와 통신을 담당하는 핸들러
@Slf4j
static class NettyClientHandler extends ChannelInboundHandlerAdapter {
TestService test;
private ChannelHandlerContext ctx;
private void init( TestService test) throws Exception {
this.test = test;
sendRequest("send msg");
}
// 서버로부터 받은 응답 처리
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
//전달 받은 내용
log.info((String)message);
//총 길이
int totTextLength = msg.getBytes(Charset.forName("EUC-KR")).length;
log.info(totTextLength);
//바이트 단위로 자르기
String = kcb.substringEucKr((String)message,1,3);
}
//메시지 전송
public void sendRequest(String request) throws Exception {
byte[] strByte = request.getBytes("euc-kr");
String strEuckr = new String(strByte,"euc-kr");
ChannelFuture fu = ctx.writeAndFlush(strEuckr).sync();
fu.addListener(new ChannelFutureListener(){
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if(future.isSuccess()) {
log.info("sendRequest() success!!");
}else {
log.info("sendRequest() fail!!");
future.cause().printStackTrace(System.err);
System.err.flush();
}
}
});
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
log.info("channelReadComplete!!");
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
//출력
log.info("exceptionCaught!!"+cause);
log.error(cause.getMessage());
log.error(cause.toString());
cause.printStackTrace();
cause.fillInStackTrace();
cause.getStackTrace();
System.out.flush();
ctx.close();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("channelActive!!");
this.ctx = ctx;
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
log.info("channelInactive!!");
this.ctx = ctx;
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
log.info("channelRegistered!!");
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
log.info("channelUnregistered!!");
}
@Override
public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
log.info("channelWritabilityChanged!!");
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
log.info("userEventTriggered");
}
}
public static String substringEucKr(String str, int start, int end) {
byte[] bytes = null;
try {
bytes = str.getBytes("EUC-KR");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte[] subBytes = new byte[end - start];
System.arraycopy(bytes, start, subBytes, 0, end - start);
try {
return new String(subBytes, "EUC-KR");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "";
}
}