最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1 概述

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

1.1 聚合 HTTP 消息

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

1.2 HTTP 壓縮

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

2 代碼實(shí)現(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請求報(bào)文聚合為完整報(bào)文,最大請求報(bào)文為10M
        pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
        //響應(yīng)報(bào)文壓縮
        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請求聚合成一個(gè)完整報(bào)文
        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 測試

啟動(dòng)服務(wù)端:

啟動(dòng)客戶端:

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

相關(guān)文章

  • SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源

    SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源

    咱們開發(fā)項(xiàng)目的過程中用到很多的開源數(shù)據(jù)庫鏈接池,比如druid、c3p0、BoneCP等等,本文主要介紹了SpringBoot配置默認(rèn)HikariCP數(shù)據(jù)源,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • 詳解Spring?中?Bean?對象的存儲(chǔ)和取出

    詳解Spring?中?Bean?對象的存儲(chǔ)和取出

    由于?Spring?擁有對象的管理權(quán),所以我們也需要擁有較為高效的對象存儲(chǔ)和取出的手段,下面我們來分別總結(jié)一下,對Spring?中?Bean?對象的存儲(chǔ)和取出知識(shí)感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Seata?AT模式前后鏡像是如何生成詳解

    Seata?AT模式前后鏡像是如何生成詳解

    這篇文章主要為大家介紹了Seata?AT模式前后鏡像是如何生成的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • Spring Transaction事務(wù)實(shí)現(xiàn)流程源碼解析

    Spring Transaction事務(wù)實(shí)現(xiàn)流程源碼解析

    此文就Spring 事務(wù)實(shí)現(xiàn)流程進(jìn)行源碼解析,我們可以借此對Spring框架更多一層理解,下面以xml形式創(chuàng)建一個(gè)事務(wù)進(jìn)行分析
    2022-09-09
  • SpringSecurity微服務(wù)實(shí)戰(zhàn)之公共模塊詳解

    SpringSecurity微服務(wù)實(shí)戰(zhàn)之公共模塊詳解

    這篇文章主要為大家介紹了SpringSecurity微服務(wù)實(shí)戰(zhàn)之公共模塊詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • java+mysql模擬實(shí)現(xiàn)銀行系統(tǒng)

    java+mysql模擬實(shí)現(xiàn)銀行系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java+mysql模擬實(shí)現(xiàn)銀行系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 圖文精講java常見分布式事務(wù)理論與解決方案

    圖文精講java常見分布式事務(wù)理論與解決方案

    對于分布式系統(tǒng),最簡單的理解就是一堆機(jī)器對外提供服務(wù),相比單體服務(wù),它可以承受更高的負(fù)載,但是分布式系統(tǒng)也帶了一系列問題,今天帶大家搞懂和分布式相關(guān)的常見理論和解決方案
    2021-11-11
  • SpringBoot項(xiàng)目中JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理的使用詳解

    SpringBoot項(xiàng)目中JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理的使用詳解

    JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理都是SpringBoot中實(shí)現(xiàn)AOP的重要技術(shù),JDK動(dòng)態(tài)代理通過反射生成代理類,適用于目標(biāo)類實(shí)現(xiàn)了接口的場景,性能較好,易用性高,但必須實(shí)現(xiàn)接口且不能代理final方法,CGLIB動(dòng)態(tài)代理通過生成子類實(shí)現(xiàn)代理
    2025-03-03
  • Springboot傳參詳解

    Springboot傳參詳解

    這篇文章主要介紹了Springboot傳參的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • RocketMQ?offset確認(rèn)機(jī)制示例詳解

    RocketMQ?offset確認(rèn)機(jī)制示例詳解

    這篇文章主要為大家介紹了RocketMQ?offset確認(rèn)機(jī)制示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09

最新評論

平遥县| 滕州市| 临朐县| 天气| 肃南| 郴州市| 麟游县| 肥城市| 依兰县| 安新县| 吴江市| 建瓯市| 林西县| 长沙县| 育儿| 石嘴山市| 桃园县| 来安县| 江口县| 巴彦淖尔市| 安岳县| 通化市| 九江市| 申扎县| 黑龙江省| 神木县| 辉南县| 阜新| 崇明县| 大冶市| 普安县| 上高县| 许昌县| 富平县| 台中市| 义马市| 延吉市| 西安市| 罗城| 秭归县| 手游|