欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何用Netty實現(xiàn)高效的HTTP服務(wù)器

 更新時間:2021年04月08日 16:34:32   作者:你攜秋月攬星河丶  
這篇文章主要介紹了如何用Netty實現(xiàn)高效的HTTP服務(wù)器,對HTTP感興趣的同學(xué)可以參考一下

1 概述

HTTP 是基于請求/響應(yīng)模式的:客戶端向服務(wù)器發(fā)送一個 HTTP 請求,然后服務(wù)器將會返回一個 HTTP 響應(yīng)。Netty 提供了多種編碼器和解碼器以簡化對這個協(xié)議的使用。一個HTTP 請求/響應(yīng)可能由多個數(shù)據(jù)部分組成,F(xiàn)ullHttpRequest 和FullHttpResponse 消息是特殊的子類型,分別代表了完整的請求和響應(yīng)。所有類型的 HTTP 消息(FullHttpRequest、LastHttpContent 等等)都實現(xiàn)了 HttpObject 接口。

(1) HttpRequestEncoder 將 HttpRequest、HttpContent 和 LastHttpContent 消息編碼為字節(jié)。
(2) HttpResponseEncoder 將 HttpResponse、HttpContent 和 LastHttpContent 消息編碼為字節(jié)。
(3) HttpRequestDecoder 將字節(jié)解碼為 HttpRequest、HttpContent 和 LastHttpContent 消息。
(4) HttpResponseDecoder 將字節(jié)解碼為 HttpResponse、HttpContent 和 LastHttpContent 消息。
(5) HttpClientCodec 和 HttpServerCodec 則將請求和響應(yīng)做了一個組合。

1.1 聚合 HTTP 消息

由于 HTTP 的請求和響應(yīng)可能由許多部分組成,因此你需要聚合它們以形成完整的消息。
為了消除這項繁瑣的任務(wù),Netty 提供了一個聚合器 HttpObjectAggregator,它可以將多個消
息部分合并為 FullHttpRequest 或者 FullHttpResponse 消息。通過這樣的方式,你將總是看
到完整的消息內(nèi)容。

1.2 HTTP 壓縮

當(dāng)使用 HTTP 時,建議開啟壓縮功能以盡可能多地減小傳輸數(shù)據(jù)的大小。雖然壓縮會帶
來一些 CPU 時鐘周期上的開銷,但是通常來說它都是一個好主意,特別是對于文本數(shù)據(jù)來
說。Netty 為壓縮和解壓縮提供了 ChannelHandler 實現(xiàn),它們同時支持 gzip 和 deflate 編碼。

2 代碼實現(xiàn)

2.1 pom

<dependencies>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.28.Final</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <!--工具-->
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.4</version>
        </dependency>
        <!--日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.6.2</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>
    </dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

2.2 HttpConsts

public class HttpConsts {

    private HttpConsts() {

    }

    public static final Integer PORT = 8888;

    public static final String HOST = "127.0.0.1";


}

2.3 服務(wù)端

2.3.1 HttpServer

@Slf4j
public class HttpServer {

    public static void main(String[] args) throws InterruptedException {

        HttpServer httpServer = new HttpServer();
        httpServer.start();
    }


    public void start() throws InterruptedException {


        EventLoopGroup boss = new NioEventLoopGroup(1);
        EventLoopGroup worker = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpServerHandlerInitial());
            ChannelFuture channelFuture = serverBootstrap.bind(HttpConsts.PORT).sync();
            log.info("服務(wù)器已開啟......");
            channelFuture.channel().closeFuture().sync();
        } finally {
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }


    }


}

2.3.2 HttpServerBusinessHandler

@Slf4j
public class HttpServerBusinessHandler extends ChannelInboundHandlerAdapter {


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        //通過編解碼器把byteBuf解析成FullHttpRequest
        if (msg instanceof FullHttpRequest) {

            //獲取httpRequest
            FullHttpRequest httpRequest = (FullHttpRequest) msg;

            try {
                //獲取請求路徑、請求體、請求方法
                String uri = httpRequest.uri();
                String content = httpRequest.content().toString(CharsetUtil.UTF_8);
                HttpMethod method = httpRequest.method();
                log.info("服務(wù)器接收到請求:");
                log.info("請求uri:{},請求content:{},請求method:{}", uri, content, method);

                //響應(yīng)
                String responseMsg = "Hello World";
                FullHttpResponse response = new DefaultFullHttpResponse(
                        HttpVersion.HTTP_1_1,HttpResponseStatus.OK,
                        Unpooled.copiedBuffer(responseMsg,CharsetUtil.UTF_8)
                );
                response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain;charset=UTF-8");
                ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
            } finally {
                httpRequest.release();
            }

        }
    }
}

2.3.3 HttpServerHandlerInitial

public class HttpServerHandlerInitial extends ChannelInitializer<SocketChannel> {


    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();

        //http請求編解碼器,請求解碼,響應(yīng)編碼
        pipeline.addLast("serverCodec", new HttpServerCodec());
        //http請求報文聚合為完整報文,最大請求報文為10M
        pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
        //響應(yīng)報文壓縮
        pipeline.addLast("compress", new HttpContentCompressor());
        //業(yè)務(wù)處理handler
        pipeline.addLast("serverBusinessHandler", new HttpServerBusinessHandler());

    }
}

2.4 客戶端

2.4.1 HttpClient

public class HttpClient {


    public static void main(String[] args) throws InterruptedException {

        HttpClient httpClien = new HttpClient();
        httpClien.start();

    }

    public void start() throws InterruptedException {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new HttpClientHandlerInitial());

            ChannelFuture f = bootstrap.connect(HttpConsts.HOST, HttpConsts.PORT).sync();
            f.channel().closeFuture().sync();

        } finally {
            eventLoopGroup.shutdownGracefully();
        }


    }

}

2.4.2 HttpClientBusinessHandler

@Slf4j
public class HttpClientBusinessHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //通過編解碼器把byteBuf解析成FullHttpResponse
        if (msg instanceof FullHttpResponse) {
            FullHttpResponse httpResponse = (FullHttpResponse) msg;
            HttpResponseStatus status = httpResponse.status();
            ByteBuf content = httpResponse.content();
            log.info("客戶端接收響應(yīng)信息:");
            log.info("status:{},content:{}", status, content.toString(CharsetUtil.UTF_8));
            httpResponse.release();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        //封裝請求信息
        URI uri = new URI("/test");
        String msg = "Hello";
        DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,
                HttpMethod.GET, uri.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes(CharsetUtil.UTF_8)));

        //構(gòu)建http請求
        request.headers().set(HttpHeaderNames.HOST, HttpConsts.HOST);
        request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
        request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());

        // 發(fā)送http請求
        ctx.writeAndFlush(request);
    }
}

2.4.3 HttpClientHandlerInitial

public class HttpClientHandlerInitial extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();

        //客戶端編碼、解碼器,請求編碼,響應(yīng)解碼
        pipeline.addLast("clientCodec", new HttpClientCodec());
        //http聚合器,將http請求聚合成一個完整報文
        pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
        //http響應(yīng)解壓縮
        pipeline.addLast("decompressor", new HttpContentDecompressor());
        //業(yè)務(wù)handler
        pipeline.addLast("clientBusinessHandler", new HttpClientBusinessHandler());

    }
}

2.5 測試

啟動服務(wù)端:

啟動客戶端:

以上就是如何用Netty實現(xiàn)高效的HTTP服務(wù)器的詳細(xì)內(nèi)容,更多關(guān)于Netty實現(xiàn)HTTP服務(wù)器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MyBatis Generator生成代碼及使用方式詳解

    MyBatis Generator生成代碼及使用方式詳解

    這篇文章主要介紹了MyBatis Generator生成代碼及使用方式的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • MybatisPlus中的刪除和邏輯刪除及區(qū)別介紹

    MybatisPlus中的刪除和邏輯刪除及區(qū)別介紹

    這篇文章主要介紹了MybatisPlus中的刪除和邏輯刪除的相關(guān)知識,刪除又分為邏輯刪除和物理刪除,那么它們有什么區(qū)別呢?在本文給大家詳細(xì)介紹,感興趣的朋友跟隨小編一起看看吧
    2020-08-08
  • Maven優(yōu)雅的添加第三方Jar包的方法

    Maven優(yōu)雅的添加第三方Jar包的方法

    下面小編就為大家?guī)硪黄狹aven優(yōu)雅的添加第三方Jar包的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java項目中添加外部jar包的兩種方式(收藏版)

    Java項目中添加外部jar包的兩種方式(收藏版)

    這篇文章主要介紹了java項目中添加外部jar包的兩種方式,第二種方式是將外部jar包引入到本地maven倉庫中,本文給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Spring boot中filter類不能注入@Autowired變量問題

    Spring boot中filter類不能注入@Autowired變量問題

    這篇文章主要介紹了Spring boot中filter類不能注入@Autowired變量問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中Lambda表達(dá)式用法介紹

    Java中Lambda表達(dá)式用法介紹

    本文詳細(xì)講解了Java中Lambda表達(dá)式的用法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • SpringCloud灰度發(fā)布的設(shè)計與實現(xiàn)詳解

    SpringCloud灰度發(fā)布的設(shè)計與實現(xiàn)詳解

    這篇文章主要介紹了SpringCloud灰度發(fā)布的設(shè)計與實現(xiàn)詳解,灰度從字面意思理解就是存在于黑與白之間的一個平滑過渡的區(qū)域,所以說對于互聯(lián)網(wǎng)產(chǎn)品來說,上線和未上線就是黑與白之分,而實現(xiàn)未上線功能平穩(wěn)過渡的一種方式就叫做灰度發(fā)布,需要的朋友可以參考下
    2023-09-09
  • 教你使用Java獲取當(dāng)前時間戳的詳細(xì)代碼

    教你使用Java獲取當(dāng)前時間戳的詳細(xì)代碼

    這篇文章主要介紹了如何使用Java獲取當(dāng)前時間戳,通過兩個java示例,向大家展示如何獲取java中的當(dāng)前時間戳,文本通過示例代碼給大家展示了java獲取當(dāng)前時間戳的方法,需要的朋友可以參考下
    2022-01-01
  • SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere

    SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere

    這篇文章主要介紹了SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • springboot使用JPA時間類型進行模糊查詢的方法

    springboot使用JPA時間類型進行模糊查詢的方法

    這篇文章主要介紹了springboot使用JPA時間類型進行模糊查詢的方法,需要的朋友可以參考下
    2018-03-03

最新評論