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

SpringBoot整合Netty服務(wù)端的方法示例

 更新時間:2024年10月30日 10:24:26   作者:m0_70554089  
本文詳細(xì)介紹了SpringBoot和Netty的整合方法,包括添加依賴、創(chuàng)建Netty服務(wù)端代碼解析類、創(chuàng)建字符解析器等步驟,以及開發(fā)過程中遇到的問題及解決方法,感興趣的可以了解一下

工作場景:使用Netty長連接實時獲取第三方接口的車輛定位數(shù)據(jù)

開發(fā)環(huán)境:JDK8

Netty基本介紹

一、什么是Netty

Netty是由JBOSS提供的一個Java開源框架,現(xiàn)為Github上的獨立項目。它是一個異步的、基于事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò)IO程序。Netty主要針對在TCP協(xié)議下,面向Clients端的高并發(fā)應(yīng)用,或者Peer-to-Peer場景下的大量數(shù)據(jù)持續(xù)傳輸?shù)膽?yīng)用。

Netty提供了一套完整的API,用于處理網(wǎng)絡(luò)IO操作,如TCP和UDP套接字。它封裝了底層的網(wǎng)絡(luò)編程細(xì)節(jié),使得開發(fā)者可以更加專注于業(yè)務(wù)邏輯的實現(xiàn)。Netty使用了一種高效的線程模型,可以處理大量的并發(fā)連接,并且具有很好的伸縮性。

Netty在多個領(lǐng)域都有廣泛的應(yīng)用,如RPC框架、游戲行業(yè)、大數(shù)據(jù)領(lǐng)域等。它支持多種傳輸類型和協(xié)議,如阻塞和非阻塞、基于BIO和NIO的UDP傳輸、本地傳輸(in-VM傳輸)、HTTP通道等。同時,Netty還提供了豐富的編解碼器,用于處理各種協(xié)議的編解碼操作。

Netty的整體結(jié)構(gòu)包括核心層和協(xié)議支持層。核心層提供了底層網(wǎng)絡(luò)通信的通用抽象和實現(xiàn),包括可擴(kuò)展的事件模型、通用的通信API、支持零拷貝的ByteBuf等。協(xié)議支持層則覆蓋了主流協(xié)議的編解碼實現(xiàn),如HTTP、SSL、Protobuf等。

總的來說,Netty是一個功能強(qiáng)大、易于使用的網(wǎng)絡(luò)應(yīng)用框架,它可以幫助開發(fā)者快速構(gòu)建高性能、高可靠性的網(wǎng)絡(luò)應(yīng)用程序。

二、Netty核心組件

Netty的核心組件主要包括以下幾個部分:

  • Channels:Channel是Netty網(wǎng)絡(luò)通信的抽象,用于進(jìn)行I/O操作。它可以被看作是Java NIO的一個基本抽象,代表了與硬件設(shè)備、文件、網(wǎng)絡(luò)socket等實體的開放連接,或者是一個能夠完成讀、寫等I/O操作的程序。Channel可以被打開或關(guān)閉,連接或斷開。
  • Callbacks(回調(diào)):Callback是一個方法,它是提供給另一個方法的引用,使得另一個方法可以在適當(dāng)?shù)臅r候回過頭來調(diào)用這個Callback方法。Callback在很多編程情形中被廣泛使用,是用于通知相關(guān)方某個操作已經(jīng)完成最常用的方法之一。
  • Futures:在Netty中,F(xiàn)utures用于異步I/O操作的結(jié)果。當(dāng)一個異步操作開始時,會立即返回一個Future,這個Future會在操作完成時得到結(jié)果或者異常。
  • Handlers:Handlers是Netty中處理I/O事件或攔截I/O操作的組件。Netty提供了許多內(nèi)置的Handler,如ChannelInboundHandler、ChannelOutboundHandler等,這些Handler可以處理各種I/O事件,如連接建立、數(shù)據(jù)接收、異常處理等。
  • Bootstrap與ServerBootstrap:Bootstrap和ServerBootstrap是Netty程序的引導(dǎo)類,主要用于配置各種參數(shù)并啟動整個Netty服務(wù)。它們都繼承自AbstractBootstrap抽象類,不同的是,Bootstrap用于客戶端引導(dǎo),而ServerBootstrap用于服務(wù)端引導(dǎo)。
  • EventLoopGroup:EventLoopGroup可以理解為一個線程池,用于處理I/O操作。在服務(wù)端程序中,一般會綁定兩個EventLoopGroup,一個用于處理Accept事件(即新的連接請求),另一個用于處理讀寫事件。

以上這些組件共同構(gòu)成了Netty的核心框架,使得開發(fā)者可以更加專注于業(yè)務(wù)邏輯的實現(xiàn),而無需過多關(guān)心底層的網(wǎng)絡(luò)通信細(xì)節(jié)。

三、SpringBoot與Netty整合

1. 添加依賴

在SpringBoot項目的pom.xml文件中,我們需要添加Netty的依賴。Netty的官方Maven倉庫地址為:https://mvnrepository.com/artifact/io.netty/netty-all

    <dependencies>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!-- Mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--   數(shù)據(jù)源     -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>

        <!--   netty     -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

    </dependencies>

2.創(chuàng)建Netty服務(wù)端

@Component
public class NettyServer {

    //負(fù)責(zé)處理接受進(jìn)來的鏈接
    private EventLoopGroup bossGroup;
    //負(fù)責(zé)處理已經(jīng)被接收的連接上的I/O操作
    private EventLoopGroup workerGroup;
    //在這個場景中,它表示服務(wù)器的綁定操作的結(jié)果
    private ChannelFuture future;

    @PostConstruct
    public void startServer() throws Exception {
        bossGroup = new NioEventLoopGroup();
        workerGroup = new NioEventLoopGroup();
        try {
            //創(chuàng)建ServerBootstrap,這個類封裝了服務(wù)器端的網(wǎng)絡(luò)配置,使得我們可以輕松地設(shè)置服務(wù)器參數(shù)
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new NettyServerInitializer());

            // 綁定端口并開始接受進(jìn)來的連接
            future = bootstrap.bind(7000).sync();

            // 等待服務(wù)器套接字關(guān)閉
            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    @PreDestroy
    public void stopServer() {
        if (future != null && !future.isDone()) {
            future.cancel(true);
        }
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }
}

代碼解析

類注解

  • @Component: 這是Spring框架的注解,表示這個類是一個組件,Spring會掃描到這個類并將其作為Bean注冊到Spring容器中。因此,這個類可以被其他Spring管理的Bean自動裝配(如果需要的話)。

類成員變量

  • bossGroup 和 workerGroup: 這兩個是EventLoopGroup的實例,用于處理網(wǎng)絡(luò)事件。bossGroup 主要負(fù)責(zé)接收進(jìn)來的連接,而 workerGroup 負(fù)責(zé)處理已經(jīng)被接收的連接上的I/O操作。
  • future: 這是一個ChannelFuture的實例,代表了一個異步的I/O操作的結(jié)果。在這個場景中,它表示服務(wù)器的綁定操作的結(jié)果。

startServer 方法

  • 該方法使用@PostConstruct注解,這意味著當(dāng)Spring容器實例化這個Bean并完成依賴注入后,會自動調(diào)用這個方法。
  • 在這個方法中,首先創(chuàng)建了兩個NioEventLoopGroup實例,一個用于boss,一個用于worker。
  • 然后,使用ServerBootstrap類來配置和啟動服務(wù)器。這個類封裝了服務(wù)器端的網(wǎng)絡(luò)配置,使得我們可以輕松地設(shè)置服務(wù)器參數(shù)。
  • 通過group方法設(shè)置boss和worker的EventLoopGroup。
  • 通過channel方法指定使用NioServerSocketChannel作為服務(wù)器的通道實現(xiàn)。
  • 通過childHandler方法設(shè)置一個新的連接被接受后如何處理。這里使用了NettyServerInitializer(這個類沒有在提供的代碼段中定義,但我們可以假設(shè)它是一個ChannelInitializer的實現(xiàn),用于配置新的Channel)。
  • 使用bind方法綁定服務(wù)器到指定的端口(這里是7000),并使用sync方法阻塞直到綁定完成。
  • 最后,使用closeFuture().sync()方法阻塞當(dāng)前線程,直到服務(wù)器套接字關(guān)閉。
  • finally塊中,無論是否發(fā)生異常,都會優(yōu)雅地關(guān)閉EventLoopGroup。

stopServer 方法

  • 該方法使用@PreDestroy注解,意味著當(dāng)Spring容器銷毀這個Bean之前,會自動調(diào)用這個方法。
  • 在這個方法中,首先檢查future是否已經(jīng)完成(即服務(wù)器是否已經(jīng)關(guān)閉)。如果沒有,就調(diào)用cancel(true)方法來嘗試取消這個操作。但是,需要注意的是,這里的cancel可能并不總是能立即停止服務(wù)器,它更多的是嘗試停止服務(wù)器,而不是強(qiáng)制停止。

3.創(chuàng)建字符解析器,用于解析收到的消息

public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch){
        ChannelPipeline pipeline = ch.pipeline();

        // 添加一個字符串解碼器,用于將接收到的ByteBuf轉(zhuǎn)換成字符串
        // 這里假設(shè)使用的是UTF-8字符集
        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));

        // 添加一個字符串編碼器,用于將發(fā)送的字符串轉(zhuǎn)換成ByteBuf
        // 這樣服務(wù)器發(fā)送字符串時,客戶端可以直接接收到字符串
        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));

        // 添加自定義的ChannelInboundHandlerAdapter來處理業(yè)務(wù)邏輯
        pipeline.addLast("handler", new MyChannelHandler());
    }
}

這段代碼定義了一個NettyServerInitializer類,它繼承自ChannelInitializer<SocketChannel>,并覆蓋了initChannel方法。在Netty中,ChannelInitializer是一個特殊的處理器,它的主要目的是幫助用戶配置一個新的ChannelChannelPipeline。當(dāng)一個新的連接被接受時,Netty會自動調(diào)用ChannelInitializerinitChannel方法來設(shè)置這個新連接的ChannelPipeline。

具體來說,initChannel方法會在以下情況下被調(diào)用:

  • 當(dāng)ServerBootstrapbind方法被調(diào)用并成功綁定到某個端口后,開始監(jiān)聽傳入的連接。
  • 一旦有客戶端連接到服務(wù)器,ServerBootstrap會接受這個連接,并創(chuàng)建一個新的SocketChannel來表示這個連接。
  • 對于這個新的SocketChannel,Netty會調(diào)用之前設(shè)置的ChannelInitializer(在這個例子中是NettyServerInitializer)的initChannel方法。
  • initChannel方法內(nèi)部會配置這個新SocketChannelChannelPipeline,添加解碼器、編碼器、業(yè)務(wù)處理器等。
  • 一旦initChannel方法執(zhí)行完畢,這個ChannelInitializer的使命就完成了,并且會從ChannelPipeline中移除自身,因為它只負(fù)責(zé)初始化工作,不參與后續(xù)的數(shù)據(jù)處理。

所以,總結(jié)來說,NettyServerInitializerinitChannel方法會在一個新的客戶端連接被服務(wù)器接受時運行,用于初始化這個新連接的ChannelPipeline。

4.創(chuàng)建Handler處理接受到的消息

public class MyChannelHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 在這里處理接收到的數(shù)據(jù)


        System.out.println("msg = " + msg);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 在這里處理異常
    }
}

四、開發(fā)中遇到的問題(暫未解決)

1.字符解析器定義之后,接收到的消息仍然亂碼

2.項目啟動后,可以訪問netty的端口號,但是訪問不了項目的端口號(已解決)

// future.channel().closeFuture().sync();把這段代碼屏蔽就可以

到此這篇關(guān)于SpringBoot整合Netty服務(wù)端的方法示例的文章就介紹到這了,更多相關(guān)SpringBoot整合Netty服務(wù)端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Windows同時配置兩個jdk環(huán)境變量的操作步驟

    Windows同時配置兩個jdk環(huán)境變量的操作步驟

    Java Development Kit (JDK) 是開發(fā)Java應(yīng)用程序的基礎(chǔ),包含了編譯器、調(diào)試器以及其他必要的工具,本指南將一步步指導(dǎo)您完成在Windows操作系統(tǒng)上同時配置兩個jdk環(huán)境變量的操作步驟,需要的朋友可以參考下
    2024-09-09
  • IDEA中Spring Initializr沒有Java8選項的解決辦法

    IDEA中Spring Initializr沒有Java8選項的解決辦法

    在使用IDEA中的Spring Initializr創(chuàng)建新項目時,Java 版本近可選擇Java17,21 ,不能選擇Java8;SpringBoot 版本也只有 3.x,所以本文給大家介紹了IDEA中Spring Initializr沒有Java8選項的解決辦法,需要的朋友可以參考下
    2024-06-06
  • 如何解決項目中java heap space的問題

    如何解決項目中java heap space的問題

    這篇文章主要介紹了如何解決項目中java heap space的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java的分支結(jié)構(gòu)與循環(huán)你知道多少

    Java的分支結(jié)構(gòu)與循環(huán)你知道多少

    這篇文章主要為大家詳細(xì)介紹了Java的分支結(jié)構(gòu)與循環(huán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Spring Boot實現(xiàn)郵件發(fā)送必會的5種姿勢

    Spring Boot實現(xiàn)郵件發(fā)送必會的5種姿勢

    這篇文章主要給大家介紹了關(guān)于Spring Boot實現(xiàn)郵件發(fā)送必會的5種姿勢,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • java實現(xiàn)輸出字符串中第一個出現(xiàn)不重復(fù)的字符詳解

    java實現(xiàn)輸出字符串中第一個出現(xiàn)不重復(fù)的字符詳解

    這篇文章主要介紹了java實現(xiàn)輸出字符串中第一個出現(xiàn)不重復(fù)的字符詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • JAVA的LIST接口的REMOVE重載方法調(diào)用原理解析

    JAVA的LIST接口的REMOVE重載方法調(diào)用原理解析

    這篇文章主要介紹了JAVA的LIST接口的REMOVE重載方法調(diào)用原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • 深入理解Java并發(fā)編程之ThreadLocal

    深入理解Java并發(fā)編程之ThreadLocal

    本文主要介紹了Java并發(fā)編程之ThreadLocal,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • fastjson對JSONObject中的指定字段重新賦值的實現(xiàn)

    fastjson對JSONObject中的指定字段重新賦值的實現(xiàn)

    這篇文章主要介紹了fastjson對JSONObject中的指定字段重新賦值的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • MyBatis簡介與配置MyBatis+Spring+MySql的方法

    MyBatis簡介與配置MyBatis+Spring+MySql的方法

    MyBatis 是一個可以自定義SQL、存儲過程和高級映射的持久層框架。這篇文章主要介紹了MyBatis簡介與配置MyBatis+Spring+MySql的方法,需要的朋友可以參考下
    2017-04-04

最新評論