亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot實現WebSocket的示例代碼

 更新時間:2024年11月19日 09:59:31   作者:絡7  
這篇文章主要為大家詳細介紹了SpringBoot實現WebSocket的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

一、環(huán)境搭建

1.創(chuàng)建SpringBoot項目,引入相關依賴

<dependencies>
        <!-- Spring Boot核心啟動器,引入常用依賴基礎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- Spring Boot對Thymeleaf模板引擎支持,用于視圖渲染 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- nekohtml庫,用于HTML解析,指定版本1.9.22 -->
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>

        <!-- JUnit 4測試框架依賴,僅測試階段用,版本4.13.2 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- JUnit Jupiter(JUnit 5部分),用于測試,僅測試環(huán)境 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Spring Boot Web開發(fā)啟動器,構建Web應用相關 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot測試相關依賴,確保應用正確性等 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>

        <!-- Spring Boot對WebSocket啟動器,實現雙向通信功能 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
    </dependencies>

2.在resources下邊創(chuàng)建static和templates文件夾

3.配置application.yml

spring:
  thymeleaf:
    cache: false # 關閉Thymeleaf頁面緩存,開發(fā)時便于即時看到模板修改效果
    encoding: UTF-8 # 模板編碼設為UTF-8,確保字符正確解析,避免亂碼
    prefix: classpath:/templates/  # 頁面映射路徑:模板文件查找路徑前綴,在類路徑下的templates目錄找
    suffix:.html # 視圖對應的模板文件后綴名
    mode: HTML5 # 設置模板模式為HTML5,遵循HTML5規(guī)范解析處理
    mvc:
      pathmatch:
        matching-strategy: ant_path_matcher # Spring MVC路徑匹配采用ant_path_matcher策略,更靈活處理URL路徑
      static-path-pattern: /static/** # 定義靜態(tài)資源訪問路徑模式,通過/static/開頭的URL可訪問static目錄下靜態(tài)資源

二、配置類開啟WebSocket支持

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @ Description: 開啟WebSocket支持
 * 用于在Spring框架的應用中配置和啟用WebSocket功能。
 * 通過相關注解和方法的定義,使得應用能夠正確地處理WebSocket連接和通信。
 */
@Configuration
public class WebSocketConfig {
    @Bean //用于將方法返回的ServerEndpointExporter對象作為一個Bean注冊到Spring的容器中
    public ServerEndpointExporter serverEndpointExporter() {
        //創(chuàng)建并返回一個ServerEndpointExporter對象。
        // ServerEndpointExporter主要作用是掃描帶有@ServerEndpoint注解的WebSocket端點類,并將它們注冊到Servlet容器中,
        // 從而使得應用能夠正確地處理WebSocket連接請求,實現WebSocket的通信功能。
        return new ServerEndpointExporter();
    }
}

三、服務層

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @ServerEndpoint 注解是一個類層次的注解,它的功能主要是將目前的類定義成一個 websocket 服務器端。
 * 注解的值將被用于監(jiān)聽用戶連接的終端訪問 URL 地址,客戶端可以通過這個 URL 來連接到 WebSocket 服務器端
 */
@Component
@Service
/**@ServerEndpoint注解用于將當前類定義為一個WebSocket服務器端端點。注解中的值"/api/websocket/{sid}"指定了客戶端連接到這個WebSocket服務器端的URL地址,
其中{sid}是一個路徑參數,可以在后續(xù)的方法中獲取并使用,不同的客戶端可以通過帶有不同sid值的這個URL來建立與服務器的WebSocket連接。
*/
 @ServerEndpoint("/api/websocket/{sid}")
public class WebSocketServer {

    private Session session;  //用戶信息
    //存放每個客戶端對應的MyWebSocket對象,保存所有已連接的客戶端對應的WebSocketServer實例
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
    //當前在線連接數,用于記錄當前有多少個客戶端與WebSocket服務器建立了連接
    private static int onlineCount = 0;
    //用于接收從客戶端連接URL路徑參數中獲取的sid值,這個sid可以用于標識不同的客戶端連接或者與客戶端相關的業(yè)務邏輯處理
    private String sid = "";


    /**
     * 連接建立成功調用的方法
     * 這個方法會處理與新連接建立相關的初始化操作,
     * 比如記錄客戶端的會話信息、將當前對象添加到已連接客戶端集合中、更新在線連接數等。
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        this.session = session;
        webSocketSet.add(this);     //加入set中,將當前新建立連接的WebSocketServer對象添加到存放所有客戶端的集合中
        this.sid = sid;
        addOnlineCount();           //在線數加1,調用方法增加當前的在線連接數統(tǒng)計值
        try {
            sendMessage("conn_success"); // 向當前新連接的客戶端發(fā)送一條消息"conn_success",告知客戶端連接成功。
            // 在控制臺打印出有新窗口開始監(jiān)聽的sid以及當前的在線人數信息。
            System.out.println("有新窗口開始監(jiān)聽:" + sid + ",當前在線人數為:" + getOnlineCount());
        } catch (IOException e) {
            // 如果發(fā)送消息過程中出現IO異常,在控制臺打印出相應提示信息
            System.out.println("websocket IO Exception");
        }
    }

    /**
     * 連接關閉調用的方法
     */
    // @OnClose注解標記的方法會在WebSocket連接關閉時被自動調用。這個方法主要處理與連接關閉相關的清理操作,
    // 比如從已連接客戶端集合中刪除對應的對象、更新在線連接數等。
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //從set中刪除,將當前關閉連接的WebSocketServer對象從存放所有客戶端的集合中移除
        subOnlineCount();           //在線數減1,調用方法減少當前的在線連接數統(tǒng)計值

        // 在控制臺打印出當前關閉連接所對應的sid值
        System.out.println("釋放的sid為:"+sid);
        // 在控制臺打印出有一連接關閉的提示信息以及更新后的當前在線人數
        System.out.println("有一連接關閉!當前在線人數為" + getOnlineCount());
    }
    /**
     * 接受到用戶信息后調用的方法
     * @param message
     * @param session
     */
    // @OnMessage注解標記的方法會在WebSocket服務器接收到客戶端發(fā)送的消息時被自動調用。這個方法主要負責處理接收到的消息,
    // 比如在控制臺打印出消息來源及內容,并且可以根據業(yè)務需求對消息進行進一步的處理,這里是將接收到的消息群發(fā)出去。
    @OnMessage
    public void onMessage(String message,Session session){
        // 在控制臺打印出收到消息的來源窗口(通過sid標識)以及消息的具體內容
        System.out.println("收到來自窗口" + sid + "的信息:" + message);
        //群發(fā)消息
        for (WebSocketServer item : webSocketSet) {
            try {
                //遍歷所有已連接的客戶端對應的WebSocketServer對象,調用每個對象的sendMessage方法將接收到的消息發(fā)送給每個客戶端,實現群發(fā)功能
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @ Param session
     * @ Param error
     */
    // @OnError注解標記的方法會在WebSocket連接過程中出現錯誤時被自動調用。這個方法主要負責處理錯誤情況,
    // 比如在控制臺打印出錯誤提示信息以及打印出詳細的錯誤堆棧信息,以便于排查問題
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("發(fā)生錯誤");
        error.printStackTrace();
    }

    /**
     * 實現服務器主動推送
     */
    public void sendMessage(String message) throws IOException {
        // 通過當前客戶端的會話對象(this.session)獲取基本的遠程通信端點(getBasicRemote),然后使用sendText方法將指定的消息發(fā)送給客戶端
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 群發(fā)自定義消息
     */
    public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {
        // 在控制臺打印出要推送消息的目標窗口(通過sid標識)以及推送的具體內容
        System.out.println("推送消息到窗口" + sid + ",推送內容:" + message);

        for (WebSocketServer item : webSocketSet) {
            try {
                //為null則全部推送
                if (sid == null) {
                    item.sendMessage(message);
                } else if (item.sid.equals(sid)) {
                    // 遍歷所有已連接的客戶端對應的WebSocketServer對象,如果sid為null則表示要向所有客戶端推送消息,
                    // 如果當前對象的sid與要推送的目標sid相等,則調用該對象的sendMessage方法將消息發(fā)送給對應的客戶端。
                    item.sendMessage(message);
                }
            } catch (IOException e) {
                // 如果在發(fā)送消息給某個客戶端過程中出現IO異常,跳過當前循環(huán),繼續(xù)嘗試給下一個客戶端發(fā)送消息。
                continue;
            }
        }
    }

    // 以下這幾個方法用于對在線連接數(onlineCount)以及存放客戶端的集合(webSocketSet)進行操作,
    // 并且都使用了synchronized關鍵字來保證在多線程環(huán)境下對這些共享資源的操作是線程安全的。

    /*該方法用于獲取當前的在線連接數。
     * 由于在線連接數(onlineCount)是一個被多個方法可能同時訪問和修改的共享變量,
     * 為了確保在多線程環(huán)境下獲取到的在線連接數是準確的,使用了synchronized關鍵字進行同步。
     * 這樣在某個線程調用此方法獲取在線連接數時,其他線程不能同時對onlineCount進行修改操作,保證了數據的一致性。
    */
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    /**
     * 該方法用于增加在線連接數。
     * 當有新的客戶端與WebSocket服務器成功建立連接時(如在onOpen方法中)會調用此方法。
     * 同樣因為onlineCount是共享變量,多個線程可能同時嘗試增加它的值(比如多個客戶端同時連接),
     * 使用synchronized關鍵字確保在同一時刻只有一個線程能夠執(zhí)行此方法對onlineCount進行自增操作,
     * 避免了數據不一致的情況,比如多個線程同時增加導致計數錯誤的問題。
     */
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    /**
     * 該方法用于減少在線連接數。
     * 當有客戶端與WebSocket服務器的連接關閉時(如在onClose方法中)會調用此方法。
     * 與增加在線連接數的方法類似,為了保證在多線程環(huán)境下對onlineCount進行準確的自減操作,
     * 使用synchronized關鍵字進行同步,防止多個線程同時對其進行操作而導致數據錯誤。
     */
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }

    /**
     * 該方法用于獲取存放所有已連接客戶端對應的WebSocketServer對象的集合(webSocketSet)。
     * 雖然這里獲取集合的操作相對簡單,但由于webSocketSet也是一個可能被多個線程訪問的共享資源,
     * 使用synchronized關鍵字進行同步,確保在獲取集合時,其他線程不會對其進行修改等操作,
     * 從而保證獲取到的集合狀態(tài)是準確的,可以安全地在獲取到集合后進行后續(xù)的遍歷等操作(如在sendInfo方法中遍歷集合發(fā)送消息)
     * @return
     */
    public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
        return webSocketSet;
    }
}

四、前端頁面

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Java 后端 WebSocket 的 Tomcat 實現</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>

<body>
Welcome<br/><input id="text" type="text" />
<button onclick="send()">發(fā)送消息</button>
<hr/>
<button onclick="closeWebSocket()">關閉WebSocket連接</button>
<hr/>
<div id="message"></div>
</body>
<script type="text/javascript">
    // 定義一個全局變量websocket,用于存儲創(chuàng)建的WebSocket對象,初始值為null
    var websocket = null;
    //判斷當前瀏覽器是否支持WebSocket
    if('WebSocket' in window) {
        // 如果瀏覽器支持WebSocket,創(chuàng)建一個WebSocket連接對象,連接到指定的服務器地址,
        // 這里連接到本地的8080端口,路徑為/api/websocket/100,其中100可能是一個示例的連接標識或參數
        websocket = new WebSocket("ws://localhost:8080/api/websocket/100");
    } else {
        // 如果瀏覽器不支持WebSocket,彈出一個警告框,提示用戶當前瀏覽器不支持WebSocket
        alert('當前瀏覽器 Not support websocket')
    }
    // 連接發(fā)生錯誤回調方法
    // 當WebSocket連接過程中出現錯誤時,會自動調用此函數
    websocket.onerror = function() {
        // 在網頁上顯示"WebSocket連接發(fā)生錯誤"的提示信息
        setMessageInnerHTML("WebSocket連接發(fā)生錯誤");
    };

    //連接成功建立回調方法
    // 當WebSocket連接成功建立時,會自動調用此函數
    websocket.onopen = function() {
        // 在網頁上顯示"WebSocket連接成功"的提示信息
        setMessageInnerHTML("WebSocket連接成功");
    }
    var U01data, Uidata, Usdata
    //接收消息回調方法
    // 當WebSocket服務器發(fā)送消息過來時,會自動調用此函數
    websocket.onmessage = function(event) {
        //在控制臺打印接收到的消息事件對象,用于調試查看消息的詳細信息
        console.log(event);
        // 將接收到的消息內容顯示在網頁上
        setMessageInnerHTML(event.data);
    }

    //連接關閉回調方法
    // 當WebSocket連接關閉時,會自動調用此函數
    websocket.onclose = function() {
        setMessageInnerHTML("WebSocket連接關閉");
    }

    //監(jiān)聽窗口關閉事件
    // 當用戶嘗試關閉瀏覽器窗口時,會自動調用此函數
    window.onbeforeunload = function() {
        // 調用closeWebSocket函數,關閉當前的WebSocket連接
        closeWebSocket();
    }

    //將消息顯示在網頁上
    function setMessageInnerHTML(innerHTML) {
        //在控制臺打印要顯示在網頁上的內容
        console.log(innerHTML)
        // 通過id獲取網頁上的div元素(id為"message"),并將傳入的內容添加到該元素的innerHTML屬性中
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //關閉WebSocket連接
    function closeWebSocket() {
        // 調用WebSocket對象的close方法,關閉當前建立的WebSocket連接
        websocket.close();
    }

    //發(fā)送消息
    function send() {
        // 通過id獲取網頁上文本輸入框(id為"text")中的值,即用戶輸入的消息內容
        var message = document.getElementById('text').value;
        // 使用WebSocket對象的send方法,將用戶輸入的消息以特定格式(這里是一個包含"msg"字段的JSON字符串)發(fā)送給服務器
        websocket.send('{"msg":"' + message + '"}');
        // 調用setMessageInnerHTML函數,將用戶輸入的消息顯示在網頁上,并添加一個換行符(&#13;)
        setMessageInnerHTML(message + "&#13;");
    }
</script>

</html>

五、運行效果

兩個瀏覽器模擬兩個用戶對話:

控制臺

到此這篇關于SpringBoot實現WebSocket的示例代碼的文章就介紹到這了,更多相關SpringBoot實現WebSocket內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 一篇文章帶你了解Maven的繼承和聚合

    一篇文章帶你了解Maven的繼承和聚合

    這篇文章主要為大家介紹了Maven的繼承和聚合,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Java中Lambda表達式的使用詳細教程

    Java中Lambda表達式的使用詳細教程

    這篇文章將通過示例為大家詳細展示Java中Lambda表達式的用法,同時也會介紹Lambda的相關知識,感興趣的小伙伴可以跟隨小編一起學習一下
    2022-05-05
  • Java詳細分析講解HashMap

    Java詳細分析講解HashMap

    在java開發(fā)中,HashMap是最常用、最常見的集合容器類之一,下面一起溫故一下,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • Java設計模式常用的七大原則總結

    Java設計模式常用的七大原則總結

    今天給大家總結了Java設計模式的七大原則,主要有單一職責原則,接口隔離原則,依賴倒轉原則,里氏替換原則等,文中有非常詳細的介紹,需要的朋友可以參考下
    2021-06-06
  • 基于Springboot2.3訪問本地路徑下靜態(tài)資源的方法(解決報錯:Not allowed to load local resource)

    基于Springboot2.3訪問本地路徑下靜態(tài)資源的方法(解決報錯:Not allowed to load local

    這篇文章主要介紹了基于Springboot2.3訪問本地路徑下靜態(tài)資源的方法(解決報錯:Not allowed to load local resource),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • MapStruct升級遇到的問題及解決方案

    MapStruct升級遇到的問題及解決方案

    MapStruct是一個用于生成類型安全,本文來介紹一下MapStruct升級遇到的問題及解決方案,具有一定的參考價值,感興趣的可以了解一下
    2024-12-12
  • 使用Netty進行編解碼的操作過程詳解

    使用Netty進行編解碼的操作過程詳解

    這篇文章主要介紹了使用Netty進行編解碼的操作過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07
  • spring-boot-maven-plugin引入不成功的解決方案

    spring-boot-maven-plugin引入不成功的解決方案

    解決Spring Boot Maven插件問題:刪除倉庫文件夾或添加指定版本號,不刪除插件會導致打包路徑錯誤,引用失敗
    2025-07-07
  • 用java實現掃雷游戲

    用java實現掃雷游戲

    這篇文章主要為大家詳細介紹了用java實現掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Spring多線程的使用以及問題詳解

    Spring多線程的使用以及問題詳解

    在我們開發(fā)系統(tǒng)過程中,經常會處理一些費時間的任務(如:向數據庫中插入大量數據),這個時候就就需要使用多線程,下面這篇文章主要給大家介紹了關于Spring多線程的使用以及問題的相關資料,需要的朋友可以參考下
    2022-05-05

最新評論