日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【Netty】使用 Netty 开发 HTTP 服务器

發布時間:2025/6/17 84 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Netty】使用 Netty 开发 HTTP 服务器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、 HTTP 服務器開發
  • 二、 HTTP 服務器代碼分析
    • 1 . Netty 開發 HTTP 服務器與 TCP 服務器對比
    • 2 . ChannelInitializer 設置
    • 3 . 自定義業務邏輯處理器
  • 三、 HTTP 服務器代碼實現
    • 1 . 服務器主程序
    • 2 . 服務器業務邏輯處理類
    • 3 . 執行結果





一、 HTTP 服務器開發



HTTP 服務器案例需求 :


① HTTP 服務器端 : 在服務器端使用 Netty 開發 HTTP 服務器 , 該 HTTP 服務器監聽 8888 端口 ;

② 瀏覽器操作 : 瀏覽器中訪問 http://127.0.0.1:8888/ 地址 , 或 http://localhost:8888/ 地址 , HTTP 服務器返回 “Hello Client” 信息 ;

③ 信息過濾 : 客戶端瀏覽器請求 HTTP 服務時 , 涉及返回字符串信息時 , 還會返回其它額外信息 , 如網站圖標等信息 , 現在我們只要服務器返回的字符串信息 , 屏蔽其它信息 , 需要開發信息過濾機制 ;





二、 HTTP 服務器代碼分析




1 . Netty 開發 HTTP 服務器與 TCP 服務器對比


HTTP 協議的服務器與 TCP 協議的服務器程序區別在于設置的 ChannelInitializer 和 Handler 中對數據的處理方式不同 ; 其它操作基本類似 , 如 :

  • 創建 BossGroup 和 WorkerGroup 兩個線程池 ;
EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup();
  • 創建 ServerBootstrap 并進行配置 , 配置項除了 ChannelInitializer 與 Handler 都一樣 ;
ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) // 設置 主從 線程組 , 分別對應 主 Reactor 和 從 Reactor.channel(NioServerSocketChannel.class) // 設置 NIO 網絡套接字通道類型.option(ChannelOption.SO_BACKLOG, 128) // 設置線程隊列維護的連接個數.childOption(ChannelOption.SO_KEEPALIVE, true) // 設置連接狀態行為, 保持連接狀態.childHandler( // 為 WorkerGroup 線程池對應的 NioEventLoop 設置對應的事件 處理器 Handler// HTTP 協議與 TCP 協議不同);
  • 綁定端口 ;
channelFuture = bootstrap.bind(8888).sync();

相同的不再贅述 , 下面針對不同的技術點進行詳細描述 ;



2 . ChannelInitializer 設置


1 . 首先要獲取該客戶端連接對應的管道 : ChannelPipeline pipeline = ch.pipeline() ;


2 . 設置 HTTP 協議的編解碼器 : pipeline.addLast(“HttpServerCodec” , new HttpServerCodec()) , 為管道加入 HTTP 協議的編解碼器 HttpServerCodec ;


3 . 設置業務邏輯處理器 Handler : pipeline.addLast(“HTTPServerHandler”, new HTTPServerHandler()) , 該業務邏輯處理器是用戶自定義的 ;


4 . 代碼示例 :

ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) // 核心示例代碼 ---------------------------------------------------------------------.childHandler( // 為 WorkerGroup 線程池對應的 NioEventLoop 設置對應的事件 處理器 Handlernew ChannelInitializer<SocketChannel>() {// 創建通道初始化對象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 該方法在服務器與客戶端連接建立成功后會回調// 獲取管道ChannelPipeline pipeline = ch.pipeline();// 為管道加入 HTTP 協議的編解碼器 HttpServerCodec,// codec 中的 co 是 coder 編碼器的意思, dec 是 decoder 解碼器的意思// 第一個字符串是編解碼器的名稱pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 為管道 Pipeline 設置處理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());}}// 核心示例代碼 ---------------------------------------------------------------------);

3 . 自定義業務邏輯處理器


1 . 類繼承 : 自定義的業務邏輯處理器 , 繼承 SimpleChannelInboundHandler<HttpObject> 類 ;


2 . 核心方法 : protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception 方法是業務邏輯處理的核心方法 , 必須由用戶自己實現 ;


3 . 判定協議請求類型 : 判定 HttpObject msg 類型是否是 HttpRequest 類型 , 如果是 , 說明該請求是 HTTP 請求 ;

if(msg instanceof HttpRequest){ //判斷該 HttpObject msg 參數是否是 Http 請求//... }

4 . 返回 HTTP 響應數據 :


① 創建 HTTP 響應對象 : DefaultFullHttpResponse , 設置 HTTP 協議的版本 , 響應狀態 , 及返回數據 ;

// 準備給客戶端瀏覽器發送的數據 ByteBuf byteBuf = Unpooled.copiedBuffer("Hello Client", CharsetUtil.UTF_8);// 設置 HTTP 版本, 和 HTTP 的狀態碼, 返回內容 DefaultFullHttpResponse defaultFullHttpResponse =new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);

② 設置 HTTP 請求頭 : 設置內容類型 , 和內容長度 ;

// 設置 HTTP 請求頭 // 設置內容類型是文本類型 defaultFullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain"); // 設置返回內容的長度 defaultFullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH,byteBuf.readableBytes());

③ 寫出 HTTP 數據 : 調用 ChannelHandlerContext ctx 參數的 writeAndFlush 即可寫出 HTTP 響應數據到客戶端 ;

// 寫出 HTTP 數據 ctx.writeAndFlush(defaultFullHttpResponse);

5 . 代碼示例 : 查看下一節的 服務器業務邏輯處理類 代碼 ;





三、 HTTP 服務器代碼實現




1 . 服務器主程序

package kim.hsl.http;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpServerCodec; import kim.hsl.netty.ServerHandler;/*** HTTP 服務器* 客戶端使用瀏覽器訪問即可*/ public class HTTPServer {public static void main(String[] args) {// 1. 創建 BossGroup 線程池 和 WorkerGroup 線程池, 其中維護 NioEventLoop 線程// NioEventLoop 線程中執行無限循環操作// BossGroup 線程池 : 負責客戶端的連接// 指定線程個數 : 客戶端個數很少, 不用很多線程維護, 這里指定線程池中線程個數為 1EventLoopGroup bossGroup = new NioEventLoopGroup(1);// WorkerGroup 線程池 : 負責客戶端連接的數據讀寫EventLoopGroup workerGroup = new NioEventLoopGroup();// 2. 服務器啟動對象, 需要為該對象配置各種參數ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup, workerGroup) // 設置 主從 線程組 , 分別對應 主 Reactor 和 從 Reactor.channel(NioServerSocketChannel.class) // 設置 NIO 網絡套接字通道類型.option(ChannelOption.SO_BACKLOG, 128) // 設置線程隊列維護的連接個數.childOption(ChannelOption.SO_KEEPALIVE, true) // 設置連接狀態行為, 保持連接狀態.childHandler( // 為 WorkerGroup 線程池對應的 NioEventLoop 設置對應的事件 處理器 Handlernew ChannelInitializer<SocketChannel>() {// 創建通道初始化對象@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// 該方法在服務器與客戶端連接建立成功后會回調// 獲取管道ChannelPipeline pipeline = ch.pipeline();// 為管道加入 HTTP 協議的編解碼器 HttpServerCodec,// codec 中的 co 是 coder 編碼器的意思, dec 是 decoder 解碼器的意思// 第一個字符串是編解碼器的名稱pipeline.addLast("HttpServerCodec" , new HttpServerCodec());// 為管道 Pipeline 設置處理器 Hanedlerpipeline.addLast("HTTPServerHandler", new HTTPServerHandler());}});System.out.println("HTTP 服務器準備完畢 ...");ChannelFuture channelFuture = null;try {// 綁定本地端口, 進行同步操作 , 并返回 ChannelFuturechannelFuture = bootstrap.bind(8888).sync();System.out.println("HTTP 服務器開始監聽 8888 端口 ...");// 關閉通道 , 開始監聽操作channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {// 出現異常后, 優雅的關閉bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}} }

2 . 服務器業務邏輯處理類

package kim.hsl.http;import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.*; import io.netty.util.CharsetUtil;/*** HTTP 服務器處理類* SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter 子類* HttpObject 指的是服務器端與客戶端處理數據時的數據類型*/ public class HTTPServerHandler extends SimpleChannelInboundHandler<HttpObject> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {if(msg instanceof HttpRequest){ //判斷該 HttpObject msg 參數是否是 Http 請求System.out.println(ctx.channel().remoteAddress() + " 客戶端請求數據 ... ");// 準備給客戶端瀏覽器發送的數據ByteBuf byteBuf = Unpooled.copiedBuffer("Hello Client", CharsetUtil.UTF_8);// 設置 HTTP 版本, 和 HTTP 的狀態碼, 返回內容DefaultFullHttpResponse defaultFullHttpResponse =new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, byteBuf);// 設置 HTTP 請求頭// 設置內容類型是文本類型defaultFullHttpResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");// 設置返回內容的長度defaultFullHttpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH,byteBuf.readableBytes());// 寫出 HTTP 數據ctx.writeAndFlush(defaultFullHttpResponse);}} }

3 . 執行結果


① 啟動服務器 : 啟動 HTTP 服務器 , 監聽 8888 端口 , 只接收 HTTP 請求 ;


② 瀏覽器訪問服務器 : 瀏覽器中輸入 http://127.0.0.1:8888/ 地址 , 即可訪問 Netty HTTP 服務器 , 服務器返回 Hello Client 字符串信息 ;


③ 服務器端日志 :

總結

以上是生活随笔為你收集整理的【Netty】使用 Netty 开发 HTTP 服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。