日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

為什么要?.NETty?

首先當然是NIO的使用,本身比較復雜,而且還存在一些問題。

除此之外,如果在項目的開發中,要實現穩定的網絡通信,就得考慮網絡的閃斷、客戶端的重復接入、客戶端的安全認證、消息的編解碼、半包讀寫……

頭大

所以,巧了,恰好有這么一個成熟穩定、性能強大、開箱即用的網絡框架擺在我們面前,相比較JAVA NIO,Netty更加出色:

  • 易用性: Netty 在 NIO 基礎上進行了更高層次的封裝,屏蔽了 NIO 的復雜性,大大降低了開發難度;Netty 提供了很多開箱即用的工具,例如常用的行解碼器、長度域解碼器等,不需要自己再實現。
  • 穩定性: Netty 更加可靠穩定,修復和完善了 JDK NIO 較多已知問題,例如臭名昭著的 select 空轉導致 CPU 消耗 100%,TCP 斷線重連,keep-alive 檢測等問題。
  • 可擴展性: Netty 的的可擴展性做的非常好,比如支持可定制化的線程模型。

我們有什么理由拒絕這么一款優秀的網絡通信框架呢?代碼怎么寫不是寫嘍!

初識Netty

什么是Netty?

Netty官方是這么定義Netty的:

Netty 是一個異步事件驅動的網絡應用程序框架,用于快速開發可維護的高性能協議服務器和客戶端。

 

組成圖-來源官方

  • Netty是一個開源的、單線程模型的 Java 網絡編程框架。
  • Netty基于 NIO ,被廣泛應用于各種網絡應用程序開發。
  • Netty支持多種協議,包括但不限于 HTTP、WebSocket、TCP、UDP 和 SSL/TLS 協議等。
  • Netty 是非阻塞的,事件驅動的框架。
  • Netty具有高性能、可擴展和易于使用的優點。

Netty的現狀?

Netty 由 JBoss 社區開發維護的,它的社區相對比較活躍:

  • https://Github.com/netty/netty:Github已經收獲31.2K星標
  • https://netty.io/:官方網站,提供了比較完整的文檔

官方目前最新的版本是5.x,,但是很不幸,已經被社區放棄開發維護,屬于廢棄版本,最新的穩定版本是4.x 。

一般使用,推薦4.x,Netty 4.x對3.x不做兼容,我們后續的學習也基于Netty 4.x版本。

誰在用Netty?

作為最流行的網絡通信框架,大量的公司選擇它作為底層網絡通信框架,包括不限于:

 

使用Netty的公司

我們可能自己沒有直接用過Netty,但其實熟悉的很多開源中間件,都用到了Netty,比如:

  • 服務治理:Apache Dubbo、gRPC。
  • 大數據:Hbase、Spark、Flink、Storm。
  • 搜索引擎:Elasticsearch。
  • 消息隊列:RocketMQ、ActiveMQ。

用到Netty的優秀產品非常多,大家感興趣可以看看:https://netty.io/wiki/related-projects.html。

從"Hello World"開始

氣氛襯托到這,不寫個Demo也過不去,還是從"Hello World"開始,我們領略一下Netty的風采。

  1. 創建一個Maven項目:這個就不用多說了吧

 

創建Maven項目

  1. 導入依賴:我們直接用4.x最新的版本
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.92.Final</version>
        </dependency>
  1. 編寫代碼:那么我們就開始編寫這個Demo的服務器和客戶端相關代碼
  2. NettyServer:基于Netty的客戶端/**
    * <p>Date: 2023/5/14 10:29</p>* <p>Author: fighter3</p>* <p>Description: Netty服務端Demo</p>*/
    public class NettyServer{
    // 服務器監聽的端口號
    private int port;
    public NettyServer(int port) {
    this.port = port;
    }/**
    * 啟動Netty服務器* @throws InterruptedException
    */
    public void run() throws InterruptedException {
    // 創建boss線程組和worker線程組
    // bossGroup 用于監聽客戶端的連接請求,將連接請求發送給 workerGroup 進行處理
    NioEventLoopGroup bossGroup = new NioEventLoopGroup();
    // workerGroup 用于處理客戶端連接的數據讀寫
    NioEventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
    // 創建 ServerBootstrap 對象,用于啟動 Netty 服務器
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    // 綁定線程池事件組
    serverBootstrap.group(bossGroup, workerGroup).channel(NIOServerSocketChannel.class)
    // 通道初始化回調函數,在啟動的時候可以自動調用.childHandler(new ChannelInitializer<SocketChannel>() {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
    ChannelPipeline pipeline = ch.pipeline();// 添加消息處理器
    pipeline.addLast(new NettyServerHandler());
    }});// 綁定端口,開始接收客戶端請求
    ChannelFuture channelFuture = serverBootstrap.bind(port).sync();System.out.println("Netty服務器監聽端口:"+port);
    // 等待服務端監聽端口關閉
    channelFuture.channel().closeFuture().sync();} finally {
    //釋放線程組資源
    bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {
    // 創建服務器對象,監聽端口號為 8888
    NettyServer server = new NettyServer(8888);
    System.out.println("============Netty服務器啟動...=============");
    // 啟動服務器
    server.run();System.out.println("============Netty服務器停止...=============");
    }}
  3. NettyServerHandler:服務器的消息處理器,用于處理各種事件/**
    * <p>Date: 2023/5/14 10:30</p>* <p>Author: fighter3</p>* <p>Description: Netty服務器消息處理器</p>*/
    public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    /**
    * 當客戶端上線的時候會觸發這個方法* @param ctx
    @throws Exception
    */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    String message="你好,靚仔!";
    ByteBuf hello = Unpooled.copiedBuffer(message, CharsetUtil.UTF_8);// 發送消息
    ctx.writeAndFlush(hello);}/**
    *當 Channel 中有來自客戶端的數據時就會觸發這個方法*/
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    ByteBuf buf = (ByteBuf) msg;System.out.println("客戶端發來的消息:" + buf.toString(CharsetUtil.UTF_8)); // 接收消息并打印輸出
    }/**
    * 當有異常時觸發這個方法*/
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    cause.printStackTrace();ctx.close();}}
  • NettyClient:使用Netty的客戶端,通過ip和端口連接服務端/**
    * <p>Date: 2023/5/14 10:32</p>* <p>Author: fighter3</p>* <p>Description: Netty客戶端Demo</p>*/
    public class NettyClient {
    // 服務器 IP
    private String host;
    // 服務器監聽的端口號
    private int port;
    public NettyClient(String host, int port) {
    this.host = host;
    this.port = port;
    }/**
    * 啟動 Netty 客戶端*/
    public void run() throws InterruptedException {
    // 創建事件循環組
    NioEventLoopGroup group = new NioEventLoopGroup();
    try {
    // 創建 Bootstrap 對象
    Bootstrap bootstrap = new Bootstrap();
    // 配置 Bootstrap 對象
    // 設置線程組
    bootstrap.group(group)// 設置客戶端通信的通道類型為NIO類型
    .channel(NioSocketChannel.class)
    .handler(new ChannelInitializer<SocketChannel>() {
    // 通道初始化回調函數,在啟動的時候可以自動調用
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
    // 添加消息處理器
    ch.pipeline().addLast(new NettyClientHandler());
    }});// 連接服務器,異步等待連接成功
    ChannelFuture channelFuture = bootstrap.connect(host, port).sync();System.out.println("===========Netty客戶端連接服務端=========");
    // 等待客戶端連接關閉
    channelFuture.channel().closeFuture().sync();} finally {
    //釋放資源
    group.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {
    // 創建客戶端對象,并連接到服務器
    NettyClient client = new NettyClient("127.0.0.1", 8888);
    // 啟動客戶端,開始發送消息
    client.run();}}
  • NettyClientHandler:Netty客戶端處理器,用于處各種事件/**
    * <p>Date: 2023/5/14 10:33</p>* <p>Author: fighter3</p>* <p>Description: Netty客戶端處理器</p>*/
    public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    /**
    * 當 Channel 準備就緒時就會觸發這個方法*/
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    String message="大佬,帶帶我!";
    ByteBuf hello = Unpooled.copiedBuffer(message, CharsetUtil.UTF_8);// 發送消息
    ctx.writeAndFlush(hello);}/**
    * 當 Channel 中有來自服務器的數據時就會觸發這個方法*/
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    ByteBuf buf = (ByteBuf) msg;System.out.println("服務端發來的消息:" + buf.toString(CharsetUtil.UTF_8)); // 接收消息并打印輸出
    }/**
    * 發生異常就會觸發這個方法*/
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    cause.printStackTrace();ctx.close();}}
  1. 運行一下:先啟動NettyServer,再啟動NettyClient,看下運行結果============Netty服務器啟動...=============
    Netty服務器監聽端口:8888
    客戶端發來的消息:大佬,帶帶我!===========Netty客戶端連接服務端=========
    服務端發來的消息:你好,靚仔!

好了,一個簡單的Netty入門Demo就寫完了,Netty是一個雙工通信的網絡框架,可以看到,服務端和客戶端,流程基本上一致,主要包括這么幾個步驟:

  1. 創建事件循環組和相關對象,用于監聽和處理網絡事件;
  2. 配置 Netty 服務器或客戶端的啟動參數,包括線程組、通道類型、TCP 參數等;
  3. 給服務器或客戶端的 ChannelPipeline 添加各種 ChannelHandler,用于處理不同的網絡事件;
  4. 綁定端口啟動服務器或連接服務器;
  5. 等待服務器或客戶端連接關閉,釋放相關資源。

 

服務器&客戶端初始化啟動流程

雖然這個Demo比較簡單,但其實已經用到了Netty里幾個比較關鍵的組件:

  1. ByteBuf:Netty 的字節容器,類似于 Java 的 ByteBuffer,但是提供了更加強大、簡便且安全的 API,用于在網絡中傳遞二進制數據;
  2. EventLoopGroup:Netty 的事件循環組,用于管理和調度連接到服務器或者從服務器連接出去的所有 Channel 上的事件循環;
  3. ServerBootstrap:Netty 的服務器啟動類,用于啟動和配置一個 TCP/IP 服務器;
  4. Bootstrap:Netty 的客戶端啟動類,用于啟動和配置一個 TCP/IP 客戶端;
  5. Channel:Netty 的核心概念,用于表示一個通信通道,可以讀取和寫入數據;
  6. ChannelPipeline:Netty 的 Channel 處理器,用于在傳入的數據上執行一組 ChannelHandler;
  7. ChannelHandler:Netty 的核心組件,用于處理各種通信事件,例如讀取數據、寫數據、建立連接等;

 

Netty的重要組件

后續,我們還會和這些組件打更多的交道。


好了,那么這期內容就到這了,這期里我們初步了解了Netty,包括什么是Netty、Netty現狀、Netty的應用,還寫了一個簡單的Demo。下一期,我們繼續深入了解Netty,敬請期待。

分享到:
標簽:Netty
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定