[java] 자바 네티 (Java Netty)에서의 클라이언트-서버 통신 모델은 무엇인가?

자바 네티 (Java Netty)는 네트워크 애플리케이션을 개발하기 위한 고성능 이벤트 기반 프레임워크입니다. 클라이언트-서버 통신은 네티에서 매우 중요한 요소입니다.

네티의 클라이언트-서버 통신 모델은 일반적으로 다음과 같은 단계를 따릅니다:

  1. 서버 소켓 채널 설정: 서버 소켓 채널을 생성하고, 포트 번호와 같은 네트워크 설정을 구성합니다.
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

try {
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup)
     .channel(NioServerSocketChannel.class)
     .childHandler(new ChannelInitializer<SocketChannel>() {
         @Override
         public void initChannel(SocketChannel ch) throws Exception {
             ch.pipeline().addLast(new MyServerHandler());
         }
     })
     .option(ChannelOption.SO_BACKLOG, 128)
     .childOption(ChannelOption.SO_KEEPALIVE, true);

    // Bind and start to accept incoming connections.
    ChannelFuture f = b.bind(port).sync();
    f.channel().closeFuture().sync();
} finally {
    workerGroup.shutdownGracefully();
    bossGroup.shutdownGracefully();
}
  1. 서버 핸들러 설정: 클라이언트로부터의 연결을 처리하는 서버 핸들러를 구현합니다. 이 핸들러는 연결된 클라이언트와의 데이터 통신을 관리합니다. 핸들러에서는 수신된 데이터를 처리하고, 응답 데이터를 클라이언트에게 보낼 수 있습니다.
public class MyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 수신된 데이터 처리
        ByteBuf buf = (ByteBuf) msg;
        byte[] data = new byte[buf.readableBytes()];
        buf.readBytes(data);
        String receivedMessage = new String(data);

        // 응답 데이터 전송
        String responseMessage = "Hello from server";
        ByteBuf responseBuf = Unpooled.copiedBuffer(responseMessage.getBytes());
        ctx.write(responseBuf);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 예외 처리
        cause.printStackTrace();
        ctx.close();
    }
}
  1. 클라이언트 소켓 채널 설정: 클라이언트에서 서버에 연결하기 위해 클라이언트 소켓 채널을 생성하고, 서버의 주소와 포트 번호를 설정합니다.
EventLoopGroup group = new NioEventLoopGroup();

try {
    Bootstrap b = new Bootstrap();
    b.group(group)
     .channel(NioSocketChannel.class)
     .handler(new ChannelInitializer<SocketChannel>() {
         @Override
         public void initChannel(SocketChannel ch) throws Exception {
             ch.pipeline().addLast(new MyClientHandler());
         }
     });

    // Start the client.
    ChannelFuture f = b.connect(host, port).sync();

    // Wait until the connection is closed.
    f.channel().closeFuture().sync();
} finally {
    group.shutdownGracefully();
}
  1. 클라이언트 핸들러 설정: 서버에서 전송된 데이터를 처리하기 위한 클라이언트 핸들러를 구현합니다. 핸들러에서는 수신된 데이터를 처리하고, 필요에 따라 응답을 보낼 수 있습니다.
public class MyClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        // 서버로 데이터 전송
        String message = "Hello from client";
        ByteBuf buf = Unpooled.copiedBuffer(message.getBytes());
        ctx.writeAndFlush(buf);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        // 서버에서 수신된 응답 처리
        ByteBuf buf = (ByteBuf) msg;
        byte[] data = new byte[buf.readableBytes()];
        buf.readBytes(data);
        String responseMessage = new String(data);

        System.out.println("Server Response: " + responseMessage);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 예외 처리
        cause.printStackTrace();
        ctx.close();
    }
}

이렇게 설정된 클라이언트와 서버는 네티의 이벤트 루프를 통해 비동기적으로 통신을 수행하며, 높은 성능과 확장성을 제공합니다. 네티를 사용하여 자바로 클라이언트-서버 통신을 구현할 수 있으며, 다양한 네트워크 애플리케이션 개발에 유용하게 활용할 수 있습니다.

참고: 자세한 내용은 네티 공식 문서를 참조하십시오.