Netty 기반 HTTP/HTTPS 프로그램 개발 방법
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.HTTPSHTTPS 를 사용 하려 면 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 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[ 네티 인 액션 ] 7. EventLoop와 스레딩 모델또한 애플리케이션의 동시성 요건이나 전반적인 복잡성 때문에 프로젝트의 수명주기 동안 다른 스레드 관련 문제가 발생할 수 있다. 1. io.netty.util.concurrent 패키지는 JDK 패키지인 java.ut...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.