国产gaysexchina男同gay,japanrcep老熟妇乱子伦视频,吃奶呻吟打开双腿做受动态图,成人色网站,国产av一区二区三区最新精品

構(gòu)建 Netty HTTP/HTTPS 應(yīng)用

2018-08-08 10:42 更新

最常見的一種協(xié)議是 HTTP/HTTPS ,尤其在智能手機上更是廣泛使用。雖然我們可以通過HTTP或HTTPS訪問一家公司的主頁,但是它其實還有別的用處。就像許多組織會通過HTTP(S)來公開 WebService API ,這樣做的目的是可以緩解獨立平臺帶來的弊端。

下面讓我們來看看 Netty 提供的 ChannelHandler是怎樣允許您使用 HTTP 和 HTTPS 而無需編寫自己的編解碼器。

HTTP Decoder, Encoder 和 Codec

HTTP 是請求-響應(yīng)模式,客戶端發(fā)送一個 HTTP 請求,服務(wù)就響應(yīng)此請求。Netty 提供了簡單的編碼、解碼器來簡化基于這個協(xié)議的開發(fā)工作。圖8.2和圖8.3顯示 HTTP 請求和響應(yīng)的方法是如何生產(chǎn)和消費的

Figure%208

  1. HTTP Request 第一部分是包含的頭信息
  2. HttpContent 里面包含的是數(shù)據(jù),可以后續(xù)有多個 HttpContent 部分
  3. LastHttpContent 標記是 HTTP request 的結(jié)束,同時可能包含頭的尾部信息
  4. 完整的 HTTP request

Figure 8.2 HTTP request component parts

Figure%208

  1. HTTP response 第一部分是包含的頭信息
  2. HttpContent 里面包含的是數(shù)據(jù),可以后續(xù)有多個 HttpContent 部分
  3. LastHttpContent 標記是 HTTP response 的結(jié)束,同時可能包含頭的尾部信息
  4. 完整的 HTTP response

Figure 8.3 HTTP response component parts

如圖8.2和8.3所示的 HTTP 請求/響應(yīng)可能包含不止一個數(shù)據(jù)部分,它總是終止于 LastHttpContent 部分。FullHttpRequest 和FullHttpResponse 消息是特殊子類型,分別表示一個完整的請求和響應(yīng)。所有類型的 HTTP 消息(FullHttpRequest ,LastHttpContent 以及那些如清單8.2所示)實現(xiàn) HttpObject 接口。

表8.2概述 HTTP 解碼器和編碼器的處理和生產(chǎn)這些消息。

Table 8.2 HTTP decoder and encoder

名稱描述
HttpRequestEncoderEncodes HttpRequest , HttpContent and LastHttpContent messages to bytes.
HttpResponseEncoderEncodes HttpResponse, HttpContent and LastHttpContent messages to bytes.
HttpRequestDecoderDecodes bytes into HttpRequest, HttpContent and LastHttpContent messages.
HttpResponseDecoderDecodes bytes into HttpResponse, HttpContent and LastHttpContent messages.

清單8.2所示的是將支持 HTTP 添加到您的應(yīng)用程序是多么簡單。僅僅添加正確的 ChannelHandler 到 ChannelPipeline 中

Listing 8.2 Add support for HTTP

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) {
            pipeline.addLast("decoder", new HttpResponseDecoder());  //1
            pipeline.addLast("encoder", new HttpRequestEncoder());  //2
        } else {
            pipeline.addLast("decoder", new HttpRequestDecoder());  //3
            pipeline.addLast("encoder", new HttpResponseEncoder());  //4
        }
    }
}
  1. client: 添加 HttpResponseDecoder 用于處理來自 server 響應(yīng)
  2. client: 添加 HttpRequestEncoder 用于發(fā)送請求到 server
  3. server: 添加 HttpRequestDecoder 用于接收來自 client 的請求
  4. server: 添加 HttpResponseEncoder 用來發(fā)送響應(yīng)給 client

HTTP消息聚合

安裝 ChannelPipeline 中的初始化之后,你能夠?qū)Σ煌?HttpObject 消息進行操作。但由于 HTTP 請求和響應(yīng)可以由許多部分組合而成,你需要聚合他們形成完整的消息。為了消除這種繁瑣任務(wù), Netty 提供了一個聚合器,合并消息部件到 FullHttpRequest 和 FullHttpResponse 消息。這樣您總是能夠看到完整的消息內(nèi)容。

這個操作有一個輕微的成本,消息段需要緩沖,直到完全可以將消息轉(zhuǎn)發(fā)到下一個 ChannelInboundHandler 管道。但好處是,你不必擔(dān)心消息碎片。

實現(xiàn)自動聚合只需添加另一個 ChannelHandler 到 ChannelPipeline。清單8.3顯示了這是如何實現(xiàn)的。

Listing 8.3 Automatically aggregate HTTP message fragments

public class HttpAggregatorInitializer extends ChannelInitializer<Channel> {

    private final boolean client;

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

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        if (client) {
            pipeline.addLast("codec", new HttpClientCodec());  //1
        } else {
            pipeline.addLast("codec", new HttpServerCodec());  //2
        }
        pipeline.addLast("aggegator", new HttpObjectAggregator(512 * 1024));  //3
    }
}
  1. client: 添加 HttpClientCodec
  2. server: 添加 HttpServerCodec 作為我們是 server 模式時
  3. 添加 HttpObjectAggregator 到 ChannelPipeline, 使用最大消息值是 512kb

HTTP 壓縮

使用 HTTP 時建議壓縮數(shù)據(jù)以減少傳輸流量,壓縮數(shù)據(jù)會增加 CPU 負載,現(xiàn)在的硬件設(shè)施都很強大,大多數(shù)時候壓縮數(shù)據(jù)時一個好主意。Netty 支持“gzip”和“deflate”,為此提供了兩個 ChannelHandler 實現(xiàn)分別用于壓縮和解壓??聪旅娲a:

HTTP Request Header

客戶端可以通過提供下面的頭顯示支持加密模式。然而服務(wù)器不是,所以不得不壓縮它發(fā)送的數(shù)據(jù)。

GET /encrypted-area HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip, deflate

下面是一個例子

Listing 8.4 Automatically compress HTTP messages

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) {
            pipeline.addLast("codec", new HttpClientCodec()); //1
            pipeline.addLast("decompressor",new HttpContentDecompressor()); //2
        } else {
            pipeline.addLast("codec", new HttpServerCodec()); //3
            pipeline.addLast("compressor",new HttpContentCompressor()); //4
        }
    }
}
  1. client: 添加 HttpClientCodec
  2. client: 添加 HttpContentDecompressor 用于處理來自服務(wù)器的壓縮的內(nèi)容
  3. server: HttpServerCodec
  4. server: HttpContentCompressor 用于壓縮來自 client 支持的 HttpContentCompressor

壓縮與依賴

注意,Java 6或者更早版本,如果要壓縮數(shù)據(jù),需要添加 jzlib 到 classpath

<dependency>
    <groupId>com.jcraft</groupId>
        <artifactId>jzlib</artifactId>
    <version>1.1.3</version>
</dependency>

使用 HTTPS

啟用 HTTPS,只需添加 SslHandler

Listing 8.5 Using HTTPS

public class HttpsCodecInitializer extends ChannelInitializer<Channel> {

    private final SslContext context;
    private final boolean client;

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

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        SSLEngine engine = context.newEngine(ch.alloc());
        pipeline.addFirst("ssl", new SslHandler(engine));  //1

        if (client) {
            pipeline.addLast("codec", new HttpClientCodec());  //2
        } else {
            pipeline.addLast("codec", new HttpServerCodec());  //3
        }
    }
}
  1. 添加 SslHandler 到 pipeline 來啟用 HTTPS
  2. client: 添加 HttpClientCodec
  3. server: 添加 HttpServerCodec ,如果是 server 模式的話

上面的代碼就是一個很好的例子,解釋了 Netty 的架構(gòu)是如何讓“重用”變成了“杠桿”。我們可以添加一個新的功能,甚至是一樣重要的加密支持,幾乎沒有工作量,只需添加一個ChannelHandler 到 ChannelPipeline。

WebSocket

HTTP 是不錯的協(xié)議,但是如果需要實時發(fā)布信息怎么做?有個做法就是客戶端一直輪詢請求服務(wù)器,這種方式雖然可以達到目的,但是其缺點很多,也不是優(yōu)秀的解決方案,為了解決這個問題,便出現(xiàn)了 WebSocket。

WebSocket 允許數(shù)據(jù)雙向傳輸,而不需要請求-響應(yīng)模式。早期的WebSocket 只能發(fā)送文本數(shù)據(jù),然后現(xiàn)在不僅可以發(fā)送文本數(shù)據(jù),也可以發(fā)送二進制數(shù)據(jù),這使得可以使用 WebSocket 構(gòu)建你想要的程序。下圖是WebSocket 的通信示例圖:

WebSocket 規(guī)范及其實現(xiàn)是為了一個更有效的解決方案。簡單的說, 一個WebSocket 提供一個 TCP 連接兩個方向的交通。結(jié)合 WebSocket API 它提供了一個替代 HTTP 輪詢雙向通信從頁面到遠程服務(wù)器。

也就是說,WebSocket 提供真正的雙向客戶機和服務(wù)器之間的數(shù)據(jù)交換。 我們不會對內(nèi)部太多的細節(jié),但我們應(yīng)該提到,雖然最早實現(xiàn)僅限于文本數(shù)據(jù),但現(xiàn)在不再是這樣,WebSocket可以用于任意數(shù)據(jù),就像一個正常的套接字。

圖8.4給出了一個通用的 WebSocket 協(xié)議。在這種情況下的通信開始于普通 HTTP ,并“升級”為雙向 WebSocket。

Figure%208

  1. Client (HTTP) 與 Server 通訊
  2. Server (HTTP) 與 Client 通訊
  3. Client 通過 HTTP(s) 來進行 WebSocket 握手,并等待確認
  4. 連接協(xié)議升級至 WebSocket

Figure 8.4 WebSocket protocol

添加應(yīng)用程序支持 WebSocket 只需要添加適當(dāng)?shù)目蛻舳嘶蚍?wù)器端WebSocket ChannelHandler 到管道。這個類將處理特殊 WebSocket 定義的消息類型,稱為“幀?!叭绫?.3所示,這些可以歸類為“數(shù)據(jù)”和“控制”幀。

Table 8.3 WebSocketFrame types

名稱描述
BinaryWebSocketFrameData frame: binary data
TextWebSocketFrameData frame: text data
ContinuationWebSocketFrameData frame: text or binary data that belongs to a previous BinaryWebSocketFrame or TextWebSocketFrame
CloseWebSocketFrameControl frame: a CLOSE request, close status code and a phrase
PingWebSocketFrameControl frame: requests the send of a PongWebSocketFrame
PongWebSocketFrameControl frame: sent as response to a PingWebSocketFrame

由于 Netty 的主要是一個服務(wù)器端技術(shù)重點在這里創(chuàng)建一個 WebSocket server 。清單8.6使用 WebSocketServerProtocolHandler 提出了一個簡單的例子。該類處理協(xié)議升級握手以及三個“控制”幀 Close, Ping 和 Pong。Text 和 Binary 數(shù)據(jù)幀將被傳遞到下一個處理程序(由你實現(xiàn))進行處理。

Listing 8.6 Support WebSocket on the server

public class WebSocketServerInitializer extends ChannelInitializer<Channel> {
    @Override
    protected void initChannel(Channel ch) throws Exception {
        ch.pipeline().addLast(
                new HttpServerCodec(),
                new HttpObjectAggregator(65536),  //1
                new WebSocketServerProtocolHandler("/websocket"),  //2
                new TextFrameHandler(),  //3
                new BinaryFrameHandler(),  //4
                new ContinuationFrameHandler());  //5
    }

    public static final class TextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
        @Override
        public void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
            // Handle text frame
        }
    }

    public static final class BinaryFrameHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {
        @Override
        public void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) throws Exception {
            // Handle binary frame
        }
    }

    public static final class ContinuationFrameHandler extends SimpleChannelInboundHandler<ContinuationWebSocketFrame> {
        @Override
        public void channelRead0(ChannelHandlerContext ctx, ContinuationWebSocketFrame msg) throws Exception {
            // Handle continuation frame
        }
    }
}
  1. 添加 HttpObjectAggregator 用于提供在握手時聚合 HttpRequest
  2. 添加 WebSocketServerProtocolHandler 用于處理色好給你寄握手如果請求是發(fā)送到"/websocket." 端點,當(dāng)升級完成后,它將會處理Ping, Pong 和 Close 幀
  3. TextFrameHandler 將會處理 TextWebSocketFrames
  4. BinaryFrameHandler 將會處理 BinaryWebSocketFrames
  5. ContinuationFrameHandler 將會處理ContinuationWebSocketFrames

加密 WebSocket 只需插入 SslHandler 到作為 pipline 第一個 ChannelHandler

詳見 Chapter 11 WebSocket

SPDY

SPDY(讀作“SPeeDY”)是Google 開發(fā)的基于 TCP 的應(yīng)用層協(xié)議,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度,優(yōu)化用戶的網(wǎng)絡(luò)使用體驗。SPDY 并不是一種用于替代 HTTP 的協(xié)議,而是對 HTTP 協(xié)議的增強。SPDY 實現(xiàn)技術(shù):

  • 壓縮報頭
  • 加密所有
  • 多路復(fù)用連接
  • 提供支持不同的傳輸優(yōu)先級

SPDY 主要有5個版本:

  • 1 - 初始化版本,但沒有使用
  • 2 - 新特性,包含服務(wù)器推送
  • 3 - 新特性包含流控制和更新壓縮
  • 3.1 - 會話層流程控制
  • 4.0 - 流量控制,并與 HTTP 2.0 更加集成

SPDY 被很多瀏覽器支持,包括 Google Chrome, Firefox, 和 Opera

Netty 支持 版本 2 和 3 (包含3.1)的支持。這些版本被廣泛應(yīng)用,可以支持更多的用戶。更多內(nèi)容詳見 Chapter 12


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號