最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot項目跟JavaScript簡單websocket使用方式

 更新時間:2026年01月31日 08:59:40   作者:心之語歌  
WebSocket是一種實現(xiàn)客戶端與服務器全雙工通信的協(xié)議,它提供了低延遲和雙向數(shù)據(jù)傳輸,適用于實時應用,通過Java的Spring框架輕松集成WebSocket,實現(xiàn)服務器端與客戶端的實時通信

websocket 簡紹

WebSocket 是一種在單個 TCP 連接上進行全雙工通信的協(xié)議。WebSocket 使得客戶端和服務器之間的數(shù)據(jù)交換變得更加簡單,允許服務端主動向客戶端推送數(shù)據(jù)。

在 WebSocket API 中,瀏覽器和服務器只需要完成一次握手,兩者之間就直接可以創(chuàng)建持久性的連接,并進行雙向數(shù)據(jù)傳輸。

WebSocket 的優(yōu)勢包括

  • 全雙工通信:允許服務器主動向客戶端發(fā)送信息,同時也能夠提供客戶端到服務器的低延遲通信。
  • 減少帶寬消耗:一旦建立連接之后,通信開銷很小,因為不需要HTTP頭部。

創(chuàng)建更豐富的交互體驗:實時更新數(shù)據(jù)的能力,使得應用能夠更加流暢地響應用戶的動作

可以通過 JavaScript 的 WebSocket 對象來創(chuàng)建一個 WebSocket 連接。

var ws = new WebSocket('ws://localhost:8080');

JavaScript 設置

處理事件

WebSocket 對象提供了幾個事件處理器來處理連接的狀態(tài)變化:

  • open:連接成功建立時觸發(fā)。
  • message:接收到消息時觸發(fā)。
  • error:發(fā)生錯誤時觸發(fā)。
  • close:連接關閉時觸發(fā)。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Example</title>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const socket = new WebSocket('ws://localhost:8080/websocket');

            socket.onopen = function (event) {
                console.log('WebSocket connection established.');
            };

            socket.onmessage = function (event) {
                console.log('Received from server:', event.data);
            };

            socket.onclose = function (event) {
                console.log('WebSocket connection closed.');
            };

            socket.onerror = function (error) {
                console.error('WebSocket error:', error);
            };

            function sendMessage() {
                let message = document.getElementById('message').value;
                socket.send(message);
                console.log('Sent message:', message);
            }
        });
    </script>
</head>
<body>
    <input type="text" id="message" placeholder="Type your message here">
    <button onclick="sendMessage()">Send Message</button>
</body>
</html>

確保你的服務器端已正確配置,并且能夠接收來自客戶端的連接請求。

使用HTTPS和WSS(加密的WebSocket)可以提高安全性,特別是在生產環(huán)境中。

如果你的服務器部署在不同的域上,請確保服務器配置允許跨域訪問。

Java 服務端設置

導jar包

通過 maven 導入 spring boot 中 集成的 websocket jar 包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

創(chuàng)建WebSocket端點

@EnableWebSocket

@EnableWebSocket 是 Spring 框架中的一個注解,用于啟用 WebSocket 支持。當一個類被標記為此注解時,Spring 會自動配置必要的組件來處理 WebSocket 請求。這個注解通常應用在一個配置類上,該類負責設置 WebSocket 的處理邏輯。

registerWebSocketHandlers

  • registerWebSocketHandlers 是 Spring WebSocket 框架中的一個重要方法,它用來注冊 WebSocket 處理器(WebSocketHandler)。這個方法是 WebSocketConfigurer 接口中定義的一個抽象方法,需要在你的配置類中實現(xiàn)。通過這個方法,你可以指定哪些路徑映射到特定的 WebSocket 處理器,并可以配置其他相關選項。
  • addHandler 方法:接受兩個參數(shù),一個是 WebSocketHandler 的實例,另一個是 WebSocket 終結點的 URL 映射。
  • setAllowedOrigins 方法:指定哪些源(域名)可以訪問你的 WebSocket 終結點。如果設置為 “*”,則表示任何源都可以訪問。
  • withSockJS 方法:這是一個可選的配置項,用于啟用 SockJS,它是一種兼容性更好的 WebSocket 實現(xiàn),能夠在不支持原生 WebSocket 的瀏覽器上使用其他傳輸方式(如長輪詢)。

接下來,定義一個WebSocket處理器類,并配置一個端點來接受WebSocket連接:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    private final WebSocketHandler webSocketHandler;

    public WebSocketConfig(WebSocketHandler webSocketHandler) {
        this.webSocketHandler = webSocketHandler;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler, "/websocket").setAllowedOrigins("*");
    }
}

這里我們定義了一個WebSocket配置類,并注冊了WebSocket處理器。/websocket 是WebSocket的端點路徑。

實現(xiàn)WebSocket處理器

afterConnectionEstablished

void afterConnectionEstablished(WebSocketSession session) throws Exception;
  • afterConnectionEstablished 是 WebSocketHandler 接口中定義的一個方法,它會在 WebSocket 連接成功建立之后被調用。這個方法為你提供了一個機會來執(zhí)行一些初始化操作,例如記錄連接信息、將連接加入到一個管理連接的集合中,或者發(fā)送初始消息給客戶端。
  • WebSocketSession session —— 表示新建立的 WebSocket 會話。
  • Exception —— 如果處理過程中出現(xiàn)任何異常,可以拋出

afterConnectionClosed

void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception;
  • afterConnectionClosed 是 WebSocketHandler 接口中定義的一個方法,它會在 WebSocket 連接關閉時被調用。這個方法允許你在連接關閉后執(zhí)行一些清理操作,例如從會話管理器中移除會話、記錄關閉事件或者發(fā)送通知給其他客戶端。
  • WebSocketSession session:表示已關閉的 WebSocket 會話。
  • CloseStatus status:表示關閉狀態(tài)的原因。CloseStatus 是一個枚舉類型,提供了標準的關閉碼和關閉原因,例如 NORMAL_CLOSURE(正常關閉)、GOING_AWAY(離開)、PROTOCOL_ERROR(協(xié)議錯誤)等。
  • 拋出:Exception —— 如果處理過程中出現(xiàn)任何異常,可以拋出。

handleTextMessage

void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception;
  • handleTextMessage 是 WebSocketHandler 接口中定義的一個方法,用于處理從客戶端接收到的文本消息。當客戶端發(fā)送文本消息時,這個方法會被調用。對于二進制消息,則會調用 handleBinaryMessage 方法。
  • WebSocketSession session:表示當前的 WebSocket 會話。
  • TextMessage message:包含從客戶端接收到的文本消息。
  • 拋出:Exception —— 如果處理過程中出現(xiàn)任何異常,可以拋出
  • 現(xiàn)在我們需要實現(xiàn)一個WebSocket處理器類來處理連接事件:
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.concurrent.ConcurrentHashMap;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.concurrent.ConcurrentHashMap;

public class WebSocketHandler extends TextWebSocketHandler {

    private static final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

    @Override
		public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        String id = session.getId();
        sessions.put(id, session);
        System.out.println("WebSocket connection established with session ID: " + id);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        String id = session.getId();
        sessions.remove(id);
        System.out.println("WebSocket connection closed with session ID: " + id);
    }

    public void sendMessageToSession(String sessionId, String message) {
        WebSocketSession session = sessions.get(sessionId);
        if (session != null && session.isOpen()) {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void broadcastMessage(String message) {
        for (WebSocketSession session : sessions.values()) {
            if (session.isOpen()) {
                try {
                    session.sendMessage(new TextMessage(message));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

現(xiàn)在我們可以使用WebSocketHandler類中的sendMessageToSession或broadcastMessage方法來發(fā)送數(shù)據(jù)給前端。

發(fā)送給特定會話:如果想要向特定的客戶端發(fā)送消息,可以使用sendMessageToSession方法。你需要知道客戶端的會話ID。

webSocketHandler.sendMessageToSession(sessionId, "Hello, client!");

廣播消息:如果你想向所有已連接的客戶端廣播消息,可以使用broadcastMessage方法

webSocketHandler.broadcastMessage("Hello, everyone!")

注銷WebSocket連接

要在Java后端注銷WebSocket連接,可以通過調用 WebSocketHandler 類中的 removeSession 方法來實現(xiàn)。例如,你可以從HTTP請求或其他服務中調用此方法:

@GetMapping("/logout/{sessionId}")
public ResponseEntity<String> logout(@PathVariable String sessionId) {
    WebSocketHandler handler = new WebSocketHandler(); // 或者通過依賴注入獲取
    handler.removeSession(sessionId);
    return ResponseEntity.ok("Session " + sessionId + " has been closed.");
}

自己定義一個 固定id 方便使用

前端 JavaScript 代碼

  • 創(chuàng)建WebSocket連接:在DOM加載完成后,創(chuàng)建一個WebSocket連接。
  • 發(fā)送握手消息:在連接建立后,發(fā)送一個包含固定ID的握手消息。
  • 處理接收到的消息:設置消息接收處理函數(shù),用于接收后端發(fā)送的數(shù)據(jù)。

后端 Java 代碼

  • 配置WebSocket處理器:配置WebSocket處理器,注冊WebSocket路徑。
  • 處理握手消息:接收前端發(fā)送的握手消息,并根據(jù)消息內容保存客戶端ID與WebSocket會話的映射。
  • 發(fā)送消息:提供方法根據(jù)客戶端ID發(fā)送消息。

前端 javascript

<!DOCTYPE html>
<html l	ang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Client Example</title>
</head>
<body>
    <input type="text" id="messageInput" placeholder="Enter your message here">
    <button id="sendButton">Send Message</button>
    <div id="log"></div>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            const socket = new WebSocket('ws://example.com/websocket');

            socket.onopen = function (event) {
                console.log('WebSocket connection established.');

                // 固定的客戶端ID
                const clientId = 'client-123';

                // 發(fā)送握手消息
                socket.send(JSON.stringify({
                    type: 'handshake',
                    clientId: clientId,
                    message: 'Hello, server!'
                }));
            };

            socket.onmessage = function (event) {
                console.log('Received from server:', event.data);
                document.getElementById('log').textContent += 'Received from server: ' + event.data + '\n';
            };

            socket.onclose = function (event) {
                console.log('WebSocket connection closed.');
                document.getElementById('log').textContent += 'WebSocket connection closed.\n';
            };

            socket.onerror = function (error) {
                console.error('WebSocket error:', error);
                document.getElementById('log').textContent += 'WebSocket error: ' + error + '\n';
            };

            document.getElementById('sendButton').addEventListener('click', function () {
                let message = document.getElementById('messageInput').value;
                if (socket.readyState === WebSocket.OPEN) {
                    socket.send(message);
                    document.getElementById('log').textContent += 'Sent message: ' + message + '\n';
                } else {
                    alert('WebSocket connection is not open.');
                }
            });
        });
    </script>
</body>
</html>

java 服務器端配置

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.socket.HandshakeMessage;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class WebSocketHandler extends TextWebSocketHandler {

    private static final Map<String, WebSocketSession> clientSessions = new ConcurrentHashMap<>();
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        String sessionId = session.getId();
        System.out.println("WebSocket connection established with session ID: " + sessionId);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        HandshakeMessage handshakeMessage = objectMapper.readValue(payload, HandshakeMessage.class);

        if ("handshake".equals(handshakeMessage.getType())) {
            String clientId = handshakeMessage.getClientId();
            String sessionId = session.getId();

            // 存儲clientId與sessionId的映射關系
            clientSessions.put(clientId, session);

            // 可以選擇回復客戶端確認握手成功的消息
            session.sendMessage(new TextMessage("Handshake successful"));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        String sessionId = session.getId();
        System.out.println("WebSocket connection closed with session ID: " + sessionId);

        // 移除會話
        clientSessions.values().removeIf(s -> s.getId().equals(sessionId));
    }

    public void sendMessageToClient(String clientId, String message) {
        WebSocketSession session = clientSessions.get(clientId);
        if (session != null && session.isOpen()) {
            try {
                session.sendMessage(new TextMessage(message));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 定義握手消息模型
    private static class HandshakeMessage {
        private String type;
        private String clientId;
        private String message;

        // Getters and setters
    }
}

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • java參數(shù)傳遞之值傳遞和引用傳遞

    java參數(shù)傳遞之值傳遞和引用傳遞

    這篇文章主要介紹了java參數(shù)傳遞之值傳遞和引用傳遞,引用了兩個代碼實例來講解,有感興趣的同學可以研究下
    2021-02-02
  • springmvc字符編碼過濾器CharacterEncodingFilter的使用

    springmvc字符編碼過濾器CharacterEncodingFilter的使用

    這篇文章主要介紹了springmvc字符編碼過濾器CharacterEncodingFilter的使用,具有很好的參考價值,希望對大家有所幫助。
    2021-08-08
  • Java文件批量重命名批量提取特定類型文件

    Java文件批量重命名批量提取特定類型文件

    這篇文章主要介紹了Java文件批量重命名批量提取特定類型文件的相關資料
    2016-08-08
  • K均值聚類算法的Java版實現(xiàn)代碼示例

    K均值聚類算法的Java版實現(xiàn)代碼示例

    這篇文章主要介紹了K均值聚類算法的Java版實現(xiàn)代碼示例,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • IDEA使用Lombok簡化POJO代碼的示例

    IDEA使用Lombok簡化POJO代碼的示例

    今天小編就為大家分享一篇關于IDEA使用Lombok簡化POJO代碼的示例,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Spring Cloud Alibaba 全解析

    Spring Cloud Alibaba 全解析

    本文給大家介紹Spring Cloud Alibaba全解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2026-02-02
  • Spring?Boot整合Zookeeper實現(xiàn)分布式鎖的場景分析

    Spring?Boot整合Zookeeper實現(xiàn)分布式鎖的場景分析

    這篇文章主要介紹了Spring?Boot整合Zookeeper實現(xiàn)分布式鎖,zk實現(xiàn)分布式鎖完全是依靠zk節(jié)點類型當中的臨時序號節(jié)點來實現(xiàn)的,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • 淺談一下Java中的堆和棧

    淺談一下Java中的堆和棧

    這篇文章主要介紹了一下Java中的堆和棧,Java數(shù)據(jù)類型在執(zhí)行過程中存儲在兩種不同形式的內存中:棧和堆,它們通常由運行Java虛擬機(JVM)的底層平臺維護,需要的朋友可以參考下
    2023-04-04
  • springboot 使用poi進行數(shù)據(jù)的導出過程詳解

    springboot 使用poi進行數(shù)據(jù)的導出過程詳解

    這篇文章主要介紹了springboot 使用poi進行數(shù)據(jù)的導出過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • 詳解JFX11+IDEA跨平臺打包發(fā)布的完美解決辦法

    詳解JFX11+IDEA跨平臺打包發(fā)布的完美解決辦法

    這篇文章主要介紹了詳解JFX11+IDEA跨平臺打包發(fā)布的完美解決辦法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06

最新評論

姚安县| 绥宁县| 体育| 乐陵市| 射阳县| 台东县| 玛多县| 阳江市| 九江县| 桃园县| 保德县| 喜德县| 望奎县| 凯里市| 宣武区| 黄梅县| 定日县| 白朗县| 犍为县| 安宁市| 甘谷县| 朔州市| 博客| 中西区| 虹口区| 长丰县| 石阡县| 高清| 黎川县| 凯里市| 东丰县| 宁陕县| 开平市| 华容县| 体育| 天峨县| 长垣县| 桃源县| 永川市| 文水县| 余庆县|