一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 如何用Netty實現高效的HTTP服務器

如何用Netty實現高效的HTTP服務器

2021-09-03 11:41你攜秋月攬星河丶 Java教程

這篇文章主要介紹了如何用Netty實現高效的HTTP服務器,對HTTP感興趣的同學可以參考一下

1 概述

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

  1. (1) HttpRequestEncoder HttpRequestHttpContent LastHttpContent 消息編碼為字節。
  2. (2) HttpResponseEncoder HttpResponseHttpContent LastHttpContent 消息編碼為字節。
  3. (3) HttpRequestDecoder 將字節解碼為 HttpRequestHttpContent LastHttpContent 消息。
  4. (4) HttpResponseDecoder 將字節解碼為 HttpResponseHttpContent LastHttpContent 消息。
  5. (5) HttpClientCodec HttpServerCodec 則將請求和響應做了一個組合。

1.1 聚合 HTTP 消息

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

1.2 HTTP 壓縮

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

2 代碼實現

如何用Netty實現高效的HTTP服務器

2.1 pom

  1. <dependencies>
  2. <dependency>
  3. <groupId>io.netty</groupId>
  4. <artifactId>netty-all</artifactId>
  5. <version>4.1.28.Final</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>junit</groupId>
  9. <artifactId>junit</artifactId>
  10. <version>4.11</version>
  11. </dependency>
  12. <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
  13. <dependency>
  14. <groupId>org.projectlombok</groupId>
  15. <artifactId>lombok</artifactId>
  16. <version>1.18.20</version>
  17. <scope>provided</scope>
  18. </dependency>
  19. <!--工具-->
  20. <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
  21. <dependency>
  22. <groupId>org.apache.commons</groupId>
  23. <artifactId>commons-lang3</artifactId>
  24. <version>3.12.0</version>
  25. </dependency>
  26. <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
  27. <dependency>
  28. <groupId>org.apache.commons</groupId>
  29. <artifactId>commons-collections4</artifactId>
  30. <version>4.4</version>
  31. </dependency>
  32. <!--日志-->
  33. <dependency>
  34. <groupId>org.slf4j</groupId>
  35. <artifactId>slf4j-api</artifactId>
  36. <version>1.7.21</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>commons-logging</groupId>
  40. <artifactId>commons-logging</artifactId>
  41. <version>1.2</version>
  42. </dependency>
  43. <dependency>
  44. <groupId>org.apache.logging.log4j</groupId>
  45. <artifactId>log4j-api</artifactId>
  46. <version>2.6.2</version>
  47. </dependency>
  48. <dependency>
  49. <groupId>log4j</groupId>
  50. <artifactId>log4j</artifactId>
  51. <version>1.2.17</version>
  52. <optional>true</optional>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.slf4j</groupId>
  56. <artifactId>slf4j-simple</artifactId>
  57. <version>1.7.25</version>
  58. </dependency>
  59. </dependencies>
  60.  
  61. <build>
  62. <plugins>
  63. <plugin>
  64. <groupId>org.apache.maven.plugins</groupId>
  65. <artifactId>maven-compiler-plugin</artifactId>
  66. <configuration>
  67. <source>8</source>
  68. <target>8</target>
  69. </configuration>
  70. </plugin>
  71. </plugins>
  72. </build>

2.2 HttpConsts

  1. public class HttpConsts {
  2.  
  3. private HttpConsts() {
  4.  
  5. }
  6.  
  7. public static final Integer PORT = 8888;
  8.  
  9. public static final String HOST = "127.0.0.1";
  10.  
  11. }

2.3 服務端

2.3.1 HttpServer

  1. @Slf4j
  2. public class HttpServer {
  3.  
  4. public static void main(String[] args) throws InterruptedException {
  5.  
  6. HttpServer httpServer = new HttpServer();
  7. httpServer.start();
  8. }
  9.  
  10. public void start() throws InterruptedException {
  11.  
  12. EventLoopGroup boss = new NioEventLoopGroup(1);
  13. EventLoopGroup worker = new NioEventLoopGroup();
  14.  
  15. try {
  16. ServerBootstrap serverBootstrap = new ServerBootstrap();
  17. serverBootstrap.group(boss, worker)
  18. .channel(NioServerSocketChannel.class)
  19. .childHandler(new HttpServerHandlerInitial());
  20. ChannelFuture channelFuture = serverBootstrap.bind(HttpConsts.PORT).sync();
  21. log.info("服務器已開啟......");
  22. channelFuture.channel().closeFuture().sync();
  23. } finally {
  24. boss.shutdownGracefully();
  25. worker.shutdownGracefully();
  26. }
  27.  
  28. }
  29.  
  30. }

2.3.2 HttpServerBusinessHandler

  1. @Slf4j
  2. public class HttpServerBusinessHandler extends ChannelInboundHandlerAdapter {
  3.  
  4. @Override
  5. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  6.  
  7. //通過編解碼器把byteBuf解析成FullHttpRequest
  8. if (msg instanceof FullHttpRequest) {
  9.  
  10. //獲取httpRequest
  11. FullHttpRequest httpRequest = (FullHttpRequest) msg;
  12.  
  13. try {
  14. //獲取請求路徑、請求體、請求方法
  15. String uri = httpRequest.uri();
  16. String content = httpRequest.content().toString(CharsetUtil.UTF_8);
  17. HttpMethod method = httpRequest.method();
  18. log.info("服務器接收到請求:");
  19. log.info("請求uri:{},請求content:{},請求method:{}", uri, content, method);
  20.  
  21. //響應
  22. String responseMsg = "Hello World";
  23. FullHttpResponse response = new DefaultFullHttpResponse(
  24. HttpVersion.HTTP_1_1,HttpResponseStatus.OK,
  25. Unpooled.copiedBuffer(responseMsg,CharsetUtil.UTF_8)
  26. );
  27. response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain;charset=UTF-8");
  28. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
  29. } finally {
  30. httpRequest.release();
  31. }
  32.  
  33. }
  34. }
  35. }

2.3.3 HttpServerHandlerInitial

  1. public class HttpServerHandlerInitial extends ChannelInitializer<SocketChannel> {
  2.  
  3. @Override
  4. protected void initChannel(SocketChannel ch) throws Exception {
  5.  
  6. ChannelPipeline pipeline = ch.pipeline();
  7.  
  8. //http請求編解碼器,請求解碼,響應編碼
  9. pipeline.addLast("serverCodec", new HttpServerCodec());
  10. //http請求報文聚合為完整報文,最大請求報文為10M
  11. pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
  12. //響應報文壓縮
  13. pipeline.addLast("compress", new HttpContentCompressor());
  14. //業務處理handler
  15. pipeline.addLast("serverBusinessHandler", new HttpServerBusinessHandler());
  16.  
  17. }
  18. }

2.4 客戶端

2.4.1 HttpClient

  1. public class HttpClient {
  2.  
  3. public static void main(String[] args) throws InterruptedException {
  4.  
  5. HttpClient httpClien = new HttpClient();
  6. httpClien.start();
  7.  
  8. }
  9.  
  10. public void start() throws InterruptedException {
  11. EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
  12. try {
  13. Bootstrap bootstrap = new Bootstrap();
  14. bootstrap.group(eventLoopGroup)
  15. .channel(NioSocketChannel.class)
  16. .handler(new HttpClientHandlerInitial());
  17.  
  18. ChannelFuture f = bootstrap.connect(HttpConsts.HOST, HttpConsts.PORT).sync();
  19. f.channel().closeFuture().sync();
  20.  
  21. } finally {
  22. eventLoopGroup.shutdownGracefully();
  23. }
  24.  
  25. }
  26.  
  27. }

2.4.2 HttpClientBusinessHandler

  1. @Slf4j
  2. public class HttpClientBusinessHandler extends ChannelInboundHandlerAdapter {
  3.  
  4. @Override
  5. public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
  6. //通過編解碼器把byteBuf解析成FullHttpResponse
  7. if (msg instanceof FullHttpResponse) {
  8. FullHttpResponse httpResponse = (FullHttpResponse) msg;
  9. HttpResponseStatus status = httpResponse.status();
  10. ByteBuf content = httpResponse.content();
  11. log.info("客戶端接收響應信息:");
  12. log.info("status:{},content:{}", status, content.toString(CharsetUtil.UTF_8));
  13. httpResponse.release();
  14. }
  15. }
  16.  
  17. @Override
  18. public void channelActive(ChannelHandlerContext ctx) throws Exception {
  19.  
  20. //封裝請求信息
  21. URI uri = new URI("/test");
  22. String msg = "Hello";
  23. DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1,
  24. HttpMethod.GET, uri.toASCIIString(), Unpooled.wrappedBuffer(msg.getBytes(CharsetUtil.UTF_8)));
  25.  
  26. //構建http請求
  27. request.headers().set(HttpHeaderNames.HOST, HttpConsts.HOST);
  28. request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
  29. request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes());
  30.  
  31. // 發送http請求
  32. ctx.writeAndFlush(request);
  33. }
  34. }

2.4.3 HttpClientHandlerInitial

  1. public class HttpClientHandlerInitial extends ChannelInitializer<SocketChannel> {
  2.  
  3. @Override
  4. protected void initChannel(SocketChannel ch) throws Exception {
  5.  
  6. ChannelPipeline pipeline = ch.pipeline();
  7.  
  8. //客戶端編碼、解碼器,請求編碼,響應解碼
  9. pipeline.addLast("clientCodec", new HttpClientCodec());
  10. //http聚合器,將http請求聚合成一個完整報文
  11. pipeline.addLast("aggregator", new HttpObjectAggregator(10 * 1024 * 1024));
  12. //http響應解壓縮
  13. pipeline.addLast("decompressor", new HttpContentDecompressor());
  14. //業務handler
  15. pipeline.addLast("clientBusinessHandler", new HttpClientBusinessHandler());
  16.  
  17. }
  18. }

2.5 測試

啟動服務端:

如何用Netty實現高效的HTTP服務器

如何用Netty實現高效的HTTP服務器

啟動客戶端:

如何用Netty實現高效的HTTP服務器

如何用Netty實現高效的HTTP服務器

以上就是如何用Netty實現高效的HTTP服務器的詳細內容,更多關于Netty實現HTTP服務器的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/qq_34125999/article/details/115488543

延伸 · 閱讀

精彩推薦
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
主站蜘蛛池模板: free性日本| 成年人免费观看 | 国产成人性毛片aaww | chinesefree普通对话 | 顶级尤物极品女神福利视频 | 青青青国产手机在线播放 | 青青国产成人久久激情911 | 欧美国产日产精品免费视频 | 欧美有码 | 免费人成网址在线观看国内 | 亚洲国产精品嫩草影院永久 | 美女扒开腿让男生桶爽漫画 | 我的妹妹最近有点怪在线观看 | 免费理伦片在线观看全网站 | 高肉h护士办公室play | 亚洲色图2 | 亚洲免费视频一区二区三区 | 91无毒不卡| 亚洲天堂伦理 | 99久久伊人精品波多野结衣 | 特黄特色大片免费视频播放 | 女老板用丝袜脚夹我好爽 | 亚洲精品丝袜在线一区波多野结衣 | 国产免费不卡视频 | 精品国产一区二区三区在线 | 国产成人在线视频播放 | 久久久这里有精品999 | 国产伦精品一区二区 | 色综合伊人色综合网站中国 | 九九99热| 美女被扒开屁股进去网 | 99热在线只有精品 | 99久久国产综合精品麻豆 | 久久精品亚洲精品国产欧美 | 激情影院网站 | 午夜精品国产自在现线拍 | 日本-区二区三区免费精品 日本破处 | 精品久久久久久久久久香蕉 | 99热这里只有精品在线 | 青青草原社区 | 波多野结衣作品在线观看 |