Netty 기반 HTTP/HTTPS 프로그램 개발 방법

11748 단어 NettyHTTPHTTPS
1.SSL/TLS 를 통 해 프로그램 보호
SSL 과 TLS 보안 프로 토 콜 은 데이터 보안 을 위해 다른 프로 토 콜 위 에 겹 쳐 져 있다.SSL/TLS 를 지원 하기 위해 자바 는 자바 x.net.ssl 패 키 지 를 제공 합 니 다.SSL context 와 SSL engine 류 는 복호화 와 암호 화 를 상당히 간단하게 합 니 다.Netty 는 SsL Handler 라 는 채널 Handler 를 통 해 이 API 를 실 현 했 는데 그 중에서 SSL Handler 는 내부 에서 SSLEngine 를 사용 하여 실제 작업 을 완성 했다.
넷 티 는 JDK 가 제공 하 는 SSLEngine 보다 더 좋 은 성능 을 가 진 OpenSSL 키 트 를 기반 으로 한 SSLEngine 구현 도 제공 했다.OpenSSL 을 사용 할 수 있다 면 Netty 프로그램 을 기본 값 으로 OpenSSL engine 를 사용 하도록 설정 할 수 있 습 니 다.사용 하지 않 으 면 Netty 는 JDK 로 되 돌아 갑 니 다.

다음 코드 는 채널 Initializer 를 사용 하여 SslHandler 를 채널 Pipeline 에 추가 하 는 방법 을 보 여 줍 니 다.

public class SslChannelInitializer extends ChannelInitializer<Channel> {

    private final SslContext context;
    private final boolean startTls;

    public SslChannelInitializer(SslContext context, boolean startTls) {
        this.context = context;
        this.startTls = startTls;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        SSLEngine engine = context.newEngine(ch.alloc());
        ch.pipeline().addFirst("ssl", new SslHandler(engine, startTls));
    }
}
대부분의 경우 Sslhandler 는 Channel Pipeline 의 첫 번 째 Channel Handler 가 될 것 입 니 다.이 는 모든 다른 Channel Handler 가 그들의 논 리 를 데이터 에 응용 한 후에 만 암호 화 할 수 있 도록 확보 합 니 다.
SSL Handler 는 표 에서 보 듯 이 악수 단계 에서 두 노드 는 서로 검증 하고 암호 화 방식 을 상의 할 수 있 습 니 다.SslHandler 를 설정 하여 행 위 를 수정 하거나 SSL/TLS 악수 가 완 료 된 후에 통 지 를 제공 할 수 있 습 니 다.악수 단계 후에 모든 데 이 터 는 암호 화 됩 니 다.
방법 이름
묘사 하 다.
setHandshakeTimeout(long, TimeUnit)
setHandshakeTimeoutMillis(long)
getHandshakeTimeoutMillis()
시간 초과 설정 및 가 져 오기,시간 초과 후 악수 Channel Future 실패 알림
setCloseNotifyTimeout(long, TimeUnit)
setCloseNotifyTimeoutMillis(long)
getCloseNotifyTimeoutMillis()
시간 초과 설정 및 가 져 오기,시간 초과 후 닫 기 알림 을 실행 하고 연결 을 닫 습 니 다.이것 은 채널 Future 를 알 리 는 데 실패 할 수도 있 습 니 다.
handshakeFuture()
악수 가 완료 되면 알림 을 받 을 채널 퓨 처 로 돌아 갑 니 다.악 수 를 이전에 실 행 했 으 면 이전 악수 결 과 를 포함 한 채널 퓨 처 로 돌아 갑 니 다.
close()
close(ChannelPipeline)
close(ChannelHandlerContext, ChannelPromise)
발송 closenotify 는 아래쪽 의 SslEngine 을 닫 고 없 애 달라 고 요청 합 니 다.
HTTP 디코더
HTTP 는 요청/응답 모드 를 기반 으로 클 라 이언 트 가 서버 에 HTTP 요청 을 보 낸 다음 서버 는 HTTP 응답 을 되 돌려 줍 니 다.Netty 는 이 프로 토 콜 에 대한 사용 을 간소화 하기 위해 다양한 인 코더 와 디코더 를 제공 합 니 다.
다음 그림 은 HTTP 요청 과 HTTP 응답 을 생산 하고 소비 하 는 방법 을 보 여 준다.


그림 에서 보 듯 이 하나의 HTTP 요청/응답 은 여러 데이터 부분 으로 구 성 될 수 있 으 며,항상 LastHttpContent 부분 으로 끝 날 수 있 습 니 다.
다음 표 는 이러한 메 시 지 를 처리 하고 생 성 하 는 HTTP 디코더 와 인 코더 에 대해 개략 적 으로 소개 한다.
명칭.
묘사 하 다.
HttpRequestEncoder
HTTPRequest,HttpContent,LastHttpContent 메 시 지 를 바이트 로 인 코딩 합 니 다.
HttpResponseEncoder
HTTPResponse,HttpContent,LastHttpContent 메 시 지 를 바이트 로 인 코딩 합 니 다.
HttpRequestDecoder
HTTPRequest,HttpContent,LastHttpContent 메시지 로 바이트 인 코딩
HttpResponseDecoder
HTTPResponse,HttpContent,LastHttpContent 메시지 로 바이트 인 코딩
다음 코드 의 HttpPipeline Initializer 클래스 는 HTTP 지원 을 프로그램 에 추가 하 는 것 이 얼마나 간단 한 지 보 여 줍 니 다.올 바른 Channel Handler 를 Channel Pipeline 에 추가 하기 만 하면 됩 니 다.

public class HttpPipelineInitializer extends ChannelInitializer<Channel> {

    private final boolean client;

    public HttpPipelineInitializer(boolean client) {
        this.client = client;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (client) {
            //       ,    HttpResponseDecoder           
            pipeline.addLast("decoder", new HttpResponseDecoder());
            //       ,    HttpRequestEncoder         
            pipeline.addLast("encoder", new HttpRequestEncoder());
        } else {
            //       ,    HttpRequestDecoder           
            pipeline.addLast("decoder", new HttpRequestDecoder());
            //       ,    HttpResponseEncoder         
            pipeline.addLast("encoder", new HttpResponseEncoder());
        }
    }
}
3.HTTP 메시지 취 합
Channel Initializer 에서 Channel Handler 를 Channel Pipeline 에 설치 하면 다양한 유형의 HTTP Object 메 시 지 를 처리 할 수 있 습 니 다.그러나 HTTP 요청 과 응답 은 여러 부분 으로 구 성 될 수 있 기 때문에 완전한 메 시 지 를 만 들 기 위해 집합 해 야 합 니 다.Netty 는 여러 메시지 부분 을 FullHttpRequest 나 FullHttpResponse 메시지 로 통합 할 수 있 는 취 합 기 를 제공 합 니 다.
다음 완전한 메 시 지 를 다음 채널 Inbound Handler 에 전달 할 수 있 을 때 까지 메시지 세그먼트 가 버퍼 링 되 어야 하기 때문에 이 조작 은 약간의 비용 이 들 기 때문에 그 가 가 져 온 장점 은 메시지 조각 에 관심 을 가 질 필요 가 없다 는 것 이다.
이러한 자동 취 합 체 제 를 도입 하 는 것 은 채널 Pipeline 에 다른 채널 Handler 를 추가 하 는 것 에 불과 합 니 다.다음 코드 는 이 점 을 어떻게 하 는 지 보 여 줍 니 다.

public class HttpAggregatorInitializer extends ChannelInitializer<Channel> {

    private final boolean isClient;

    public HttpAggregatorInitializer(boolean isClient) {
        this.isClient = isClient;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (isClient) {
            //       ,    HttpClientCodec
            pipeline.addLast("codec", new HttpClientCodec());
        } else {
            //       ,    HttpServerCodec
            pipeline.addLast("codec", new HttpServerCodec());
        }
        //           512KB   HTTPObjectAggregator     ChannelPipeline
        pipeline.addLast("aggregator", new HttpObjectAggregator(512 * 1024));
    }
}
4.HTTP 압축
HTTP 를 사용 할 때 전송 데이터 의 크기 를 최대한 줄 이기 위해 압축 기능 을 켜 는 것 을 권장 합 니 다.압축 은 약간의 소 모 를 가 져 올 수 있 지만,일반적으로 그것 은 모두 좋 은 생각 이다.특히 텍스트 데이터 에 있어 서 는.
Netty 는 압축 과 압축 해 제 를 위해 모두 Channel Handler 를 제공 합 니 다.gzip 과 deflate 인 코딩 을 동시에 지원 합 니 다.
클 라 이언 트 는 다음 과 같은 헤드 정 보 를 제공 함으로써 서버 가 지원 하 는 압축 형식 을 표시 할 수 있다.
GET /encrypted-area HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate
그러나 주의해 야 할 것 은 서버 가 보 낸 데 이 터 를 압축 할 의무 가 없다 는 점 이다.

public class HttpCompressionInitializer extends ChannelInitializer<Channel> {

    private final boolean isClient;

    public HttpCompressionInitializer(boolean isClient) {
        this.isClient = isClient;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (isClient) {
            //       ,    HTTPClientCodec
            pipeline.addLast("codec", new HttpClientCodec());
            //       ,    HttpContentDecompressor              
            pipeline.addLast("decompressor", new HttpContentDecompressor());
        } else {
            //       ,    HttpServerCodec
            pipeline.addLast("codec", new HttpServerCodec());
            //       ,    HttpContentDecompressor      
            pipeline.addLast("decompressor", new HttpContentDecompressor());
        }
    }
}
5.HTTPS
HTTPS 를 사용 하려 면 SslHandler 를 Channel Pipeline 의 Channel Handler 조합 에 추가 하기 만 하면 됩 니 다.

public class HttpsCodecInitializer extends ChannelInitializer<Channel> {

    private final SslContext context;
    private final boolean isClient;

    public HttpsCodecInitializer(SslContext context, boolean isClient) {
        this.context = context;
        this.isClient = isClient;
    }

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        SSLEngine engine = context.newEngine(ch.alloc());
        pipeline.addLast("ssl", new SslHandler(engine));
        if (isClient) {
            pipeline.addLast("codec", new HttpClientCodec());
        } else {
            pipeline.addLast("codec", new HttpServerCodec());
        } 
    }
}
6.웹 소켓
WebSocket 은 장기 적 으로 존재 하 는 문 제 를 해결 했다.바 텀 프로 토 콜(HTTP)이 요청/응답 모드 의 상호작용 서열 인 이상 어떻게 실시 간 으로 정 보 를 발표 합 니까?AJAX 는 어느 정도 이 문 제 를 해 결 했 지만 데이터 흐름 은 클 라 이언 트 가 보 낸 요청 에 의 해 작 동 되 었 습 니 다.
웹 소켓 은 단일 TCP 연결 에 양 방향 통신 을 제공 하여 웹 페이지 와 원 격 서버 간 의 양 방향 통신 에 HTTP 폴 링 을 대체 하 는 방안 을 제공 합 니 다.
응용 프로그램 에 WebSocket 에 대한 지원 을 추가 하려 면 적당 한 클 라 이언 트 나 서버 WebSocket Channel Handler 를 Channel Pipeline 에 추가 해 야 합 니 다.이 클래스 는 웹 소켓 이 정의 하 는 프레임 이 라 고 불 리 는 특수 한 메시지 형식 을 처리 합 니 다.표 에서 보 듯 이 웹 소켓 프레임 은 데이터 프레임 이나 제어 프레임 으로 분류 할 수 있 습 니 다.
명칭.
묘사 하 다.
BinaryWebSocketFrame
데이터 프레임:바 이 너 리 데이터
TextWebSocketFrame
데이터 프레임:텍스트 데이터
ContinuationWebSocketFrame
데이터 프레임:이전 Binary WebSocketFrame 또는 TextWebSocketFrame 에 속 하 는 텍스트 나 바 이 너 리 데이터
CloseWebSocketFrame
제어 프레임:하나의 CLOSE 요청,닫 힌 상태 코드 및 닫 힌 원인
PingWebSocketFrame
제어 프레임:PongWebSocketFrame 요청
PongWebSocketFrame
제어 프레임:PingWebSocketFrame 요청 에 대한 응답
Netty 는 주로 서버 엔 드 기술 이기 때문에 웹 소켓 서버 를 만 드 는 데 중점 을 두 고 있 습 니 다.다음 코드 는 WebSocketChannel Handler 를 사용 하 는 간단 한 예 시 를 보 여 줍 니 다.이 종 류 는 프로 토 콜 업그레이드 악수 와 세 가지 제어 프레임 인 Close,Ping 과 Pong,Text 와 Binary 데이터 프레임 을 다음 Channel Handler 에 전달 하여 처리 합 니 다.

public class WebSocketServerInitializer extends ChannelInitializer<Channel> {

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ch.pipeline().addLast(
                new HttpServerCodec(),
                new HttpObjectAggregator(65536),
                //           /websocket,        
                new WebSocketServerProtocolHandler("/websocket"),
                // TextFrameHandler    TextWebSocketFrame
                new TextFrameHandler(),
                // BinaryFrameHandler    BinaryWebSocketFrame
                new BinaryFrameHandler(),
                // ContinuationFrameHandler    Continuation WebSocketFrame
                new ContinuationFrameHandler());
    }

    public static final class TextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

        @Override
        protected void messageReceived(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            // do something
        }
    }

    public static final class BinaryFrameHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {

        @Override
        protected void messageReceived(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) throws Exception {
            // do something
        }
    }

    public static final class ContinuationFrameHandler extends SimpleChannelInboundHandler<ContinuationWebSocketFrame> {

        @Override
        protected void messageReceived(ChannelHandlerContext ctx, ContinuationWebSocketFrame msg) throws Exception {
            // do something
        }
    }
}
다음은 Netty 기반 HTTP/HTTPS 프로그램 을 어떻게 개발 하 는 지 에 대한 자세 한 내용 입 니 다.Netty HTTP/HTTPS 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기