1, 2, 3 에코 서버 하나 쓰세요.

6784 단어 Netty


echo 서버 쓰기


Netty가 구현하는 echo 서버는 다음과 같습니다.
  • 한 서버handler: 이 구성 요소는 서버의 업무 논리를 실현하고 연결이 만들어진 후와 정보를 받은 후에 어떻게 처리해야 하는지를 결정합니다
  • Bootstrapping: 이것은 서버를 설정하는 시작 코드입니다.연결 요청을 감청하기 위해 서버에 연결된 포트를 최소한 설정해야 합니다.

  • ChannelHandler를 통해 서버 논리 구현


    Echo Server는 수신된 데이터의 복제본을 클라이언트에게 전송합니다.따라서 우리는 입국 이벤트를 처리하는 방법을 정의하기 위해 채널 인바운드 Handler 인터페이스를 실현해야 한다.우리의 응용은 매우 간단하기 때문에 Channel Inbound Handler Adapter를 계승하기만 하면 된다.이 클래스는 기본 Channel InboundHandler 구현을 제공하기 때문에 다음 방법을 덮어쓰기만 하면 됩니다.
  • channelRead() - 모든 정보가 사이트에 호출됩니다
  • channelReadComplete () - 프로세서의 마지막 channelread () 가 현재 일괄 처리의 마지막 메시지일 때 호출됩니다
  • exceptionCaught() - 작업을 읽을 때 이상을 포착할 때 호출합니다

  • EchoServerHandler 코드는 다음과 같습니다.
    Listing 2.2 EchoServerHandler
    @Sharable                                        //1
    public class EchoServerHandler extends
            ChannelInboundHandlerAdapter {
    
        @Override
        public void channelRead(ChannelHandlerContext ctx,
            Object msg) {
            ByteBuf in = (ByteBuf) msg;
            System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8));        //2
            ctx.write(in);                            //3
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)//4
            .addListener(ChannelFutureListener.CLOSE);
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx,
            Throwable cause) {
            cause.printStackTrace();                //5
            ctx.close();                            //6
        }
    }
    

    1. @Sharable 표지와 같은 실례는 채널에서 공유할 수 있다
    2. 로그 메시지를 콘솔에 출력
    3. 받은 메시지를 발송자에게 되돌려줍니다.주의해라, 이것은 아직 데이터를 씻지 않았다
    4. 모든 심사 대기 메시지를 원격 노드로 씻는다.채널을 닫으면 작업이 완료됩니다.
    5. 이상 스택 추적 인쇄
    6. 채널 닫기
    이런 채널 Handler를 사용하는 방식은 관심사 분리의 디자인 원칙을 구현하고 업무 논리의 교체 개발의 요구를 간소화시켰다.처리 절차가 간단하다.그것의 모든 방법은'훅(갈고리)'이 활동 주기에 적당한 점까지 덮어쓸 수 있다.분명히 우리는 channelRead를 덮어씁니다. 수신된 모든 데이터를 처리해야 하기 때문입니다.
    exceptionCaught를 덮어쓰면 Throwable의 하위 유형에 대응할 수 있습니다.이 경우 알 수 없는 상태일 수 있는 모든 연결을 기록하고 닫습니다.보통 연결 오류에서 복구하기 어려워서 원격 연결을 아예 닫습니다.물론 오류에서 회복될 수 있기 때문에 더욱 복잡한 조치로 이런 상황을 식별하고 처리할 수 있다.
    만약 이상이 잡히지 않았다면 무슨 일이 일어났을까?
    각 Channel은 Channel Pipeline과 연관되어 있으며 이는 ChannelHandler 인스턴스의 체인을 나타냅니다.어댑터 처리의 실현은 단지 하나의 처리 방법을 체인에 전송된 다음 프로세서로 호출할 뿐이다.따라서 Netty 프로그램이 exceptionCaught를 덮어쓰지 않으면 이 오류는 최종적으로 Channel Pipeline에 도착하고 경고가 기록됩니다.이 때문에 exceptionCaught를 실현하는 채널 Handler를 최소한 하나 제공해야 한다.
    중요한 점은 다음과 같습니다.
  • ChannelHandler는 다양한 유형의 이벤트를 호출합니다
  • 응용 프로그램이 ChannelHandler 연결 이벤트의 생명 주기를 실현하거나 확장하고 사용자 정의 응용 논리를 제공합니다

  • 부트 서버


    업무 핵심 처리 논리인 Echo ServerHandler를 알게 되면 서버 자체를 안내하겠습니다.
  • 들어오는 연결 요청을 감청하고 수신합니다
  • 입국 메시지에 대한 EchoServerHandler 실례를 알리기 위해 채널을 설정합니다

  • Transport(전송)
    이 절에서 "transport(전송)"라는 단어를 만날 수 있습니다.네트워크의 다중 보기 프로토콜에서 전송층은 끝에서 끝까지, 또는 호스트에서 호스트까지의 통신 서비스를 제공한다.인터넷 통신의 기초는 TCP 전송이다.우리가 용어인'NIO transport'를 사용할 때 우리는 전송의 실현을 가리킨다. 이것은 대부분 TCP와 같다. 일부 자바 NIO의 실현을 제외하고는 서버 측의 성능 향상을 제공한다.Transport는 4장에서 자세히 설명합니다.
    Listing 2.3 EchoServer
    public class EchoServer {
    
        private final int port;
    
        public EchoServer(int port) {
            this.port = port;
        }
            public static void main(String[] args) throws Exception {
            if (args.length != 1) {
                System.err.println(
                        "Usage: " + EchoServer.class.getSimpleName() +
                        " ");
                return;
            }
            int port = Integer.parseInt(args[0]);        //1
            new EchoServer(port).start();                //2
        }
    
        public void start() throws Exception {
            NioEventLoopGroup group = new NioEventLoopGroup(); //3
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(group)                                //4
                 .channel(NioServerSocketChannel.class)        //5
                 .localAddress(new InetSocketAddress(port))    //6
                 .childHandler(new ChannelInitializer() { //7
                     @Override
                     public void initChannel(SocketChannel ch) 
                         throws Exception {
                         ch.pipeline().addLast(
                                 new EchoServerHandler());
                     }
                 });
    
                ChannelFuture f = b.bind().sync();            //8
                System.out.println(EchoServer.class.getName() + " started and listen on " + f.channel().localAddress());
                f.channel().closeFuture().sync();            //9
            } finally {
                group.shutdownGracefully().sync();            //10
            }
        }
    
    }
    

    1. 포트 값을 설정합니다(NumberFormateException 이 포트 매개변수의 형식이 올바르지 않은 경우).
    2. 호출 서버의 start() 방법
    3. EventLoopGroup 만들기
    4. ServerBootstrap 만들기
    5. NIO를 사용하는 전송 채널 지정
    6. socket 주소를 설정하고 선택한 포트를 사용합니다
    7. 채널에 EchoServerHandler를 추가하는 ChannelPipeline
    8. 귀속된 서버;sync 서버 종료 대기
    9. 채널과 블록이 닫힐 때까지 닫기
    10. 전원이 꺼진 EventLoopGroup에서 모든 리소스를 방출합니다.
    이 예에서 코드는 ServerBootstrap 인스턴스를 만듭니다(4단계).NIO 전송에 사용되기 때문에, NioEventLoopGroup(3)이 새 연결을 수락하고 처리하도록 지정하고, NioServerSocketChannel(5)을 채널 유형으로 지정했습니다.그 다음에 로컬 주소를 InetSocketAddress로 설정합니다. 선택한 포트(6)와 같습니다.서버는 새 연결 요청을 감청하기 위해 이 주소를 연결합니다.
    일곱 번째 단계는 관건이다. 여기서 우리는 특수한 종류, 채널 이니셔티브를 사용한다.새로운 연결이 받아들여지면 새로운 하위 채널이 만들어지고, 채널 Initializer는 저희 에코 서버 Handler의 실례를 채널의 채널 Pipeline에 추가합니다.앞에서 말한 바와 같이, 이 프로세서는 입국 정보가 있으면 통지될 것이다.
    NIO는 확장성이 뛰어나지만 정확한 구성은 간단하지 않습니다.특히 다선정은 정확하게 처리하기도 쉽지 않다.다행히도 넷티의 디자인은 대부분의 복잡성을 봉인했다. 특히 추상적이다. 예를 들어 Event Loop Group, Socket Channel과 Channel Initializer 등이다. 그 중 하나는 더욱 상세하게 제3장에서 토론할 것이다.
    8단계에서 귀속된 서버는 귀속이 완료될 때까지 기다립니다.(sync () 를 호출하는 이유는 현재 루틴이 막히기 때문입니다) 9단계 프로그램에서 서버 채널이 닫히기를 기다립니다. (채널의 CloseFuture에서sync () 를 호출하기 때문입니다.이제 EventLoop Group을 닫고 생성된 모든 스레드 (10) 를 포함하여 모든 자원을 방출할 수 있습니다.
    NIO는 현재 가장 광범위하게 사용되고 있는 전송이기 때문에 확장성과 철저한 비동기화 덕분입니다.그러나 서로 다른 전송의 실현도 가능하다.예를 들어, 이 구현 예에서 OIO 전송을 사용하는 경우 OioServerSocketChannel 및 OioEventLoopGroup을 지정합니다.Netty의 구조는 전송 정보를 포함하여 4장에 포함될 것이다.그 동안 우리는 서버에서 실행된 것을 되돌아보고 중요한 절차만 연구했다.
    서버의 주 코드 구성 요소는
  • Echo ServerHandler가 실현한 업무 논리
  • main () 방법에서 서버를 안내했습니다

  • 다음 단계를 수행하는 데 필요한 단계는 다음과 같습니다.
  • 서버를 유도하고 귀속시키기 위해 ServerBootstrap 인스턴스를 만듭니다
  • NioEventLoop Group 인스턴스를 생성하고 할당하여 이벤트 처리를 처리합니다. 예를 들어 새로운 연결과 데이터 읽기/쓰기를 수락합니다..
  • 로컬 InetSocketAddress를 서버에 바인딩하도록 지정합니다
  • EchoServerHandler 실례를 통해 모든 새로운 채널을 초기화합니다
  • 마지막으로 ServerBootstrap을 호출합니다.bind () 귀속 서버

  • 이렇게 하면 서버 초기화가 완성되어 사용할 수 있다.

    좋은 웹페이지 즐겨찾기