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

Spring Boot中WebSocket常用使用方法詳解

 更新時(shí)間:2025年07月04日 11:39:38   作者:java干貨倉庫  
本文從WebSocket的基礎(chǔ)概念出發(fā),詳細(xì)介紹了Spring Boot集成WebSocket的步驟,并重點(diǎn)講解了常用的使用方法,包括簡單消息收發(fā)、點(diǎn)對點(diǎn)消息發(fā)送、消息攔截與認(rèn)證,以及不使用接口而是基于注解的WebSocket實(shí)現(xiàn)方式,感興趣的朋友一起看看吧

在實(shí)時(shí)性要求較高的應(yīng)用場景,如在線聊天、實(shí)時(shí)數(shù)據(jù)監(jiān)控、股票行情推送等,傳統(tǒng)的HTTP協(xié)議由于其請求-響應(yīng)的模式,無法高效實(shí)現(xiàn)服務(wù)器與客戶端之間的雙向?qū)崟r(shí)通信。而WebSocket協(xié)議的出現(xiàn)解決了這一難題,它允許在單個(gè)TCP連接上進(jìn)行全雙工通信,使得服務(wù)器和客戶端可以隨時(shí)主動(dòng)發(fā)送消息。Spring Boot對WebSocket提供了良好的支持,極大地簡化了開發(fā)流程。本文將從入門到精通,詳細(xì)介紹Spring Boot中WebSocket的常用使用方法。

一、WebSocket基礎(chǔ)概念

1.1 什么是WebSocket

WebSocket是一種網(wǎng)絡(luò)通信協(xié)議,于2011年被IETF定為標(biāo)準(zhǔn)RFC 6455,并被HTML5所支持 。與HTTP協(xié)議不同,WebSocket在建立連接后,通信雙方可以隨時(shí)主動(dòng)發(fā)送和接收數(shù)據(jù),無需像HTTP那樣每次通信都要建立新的連接,從而減少了開銷,提高了實(shí)時(shí)性。

1.2 WebSocket與HTTP的區(qū)別

特性HTTPWebSocket
通信模式客戶端發(fā)起請求,服務(wù)器響應(yīng)(單向)全雙工通信(雙向)
連接方式每次請求都需建立新連接一次握手建立持久連接
數(shù)據(jù)格式通常為文本(JSON、XML等)支持文本和二進(jìn)制數(shù)據(jù)
應(yīng)用場景適用于一般的Web頁面請求適用于實(shí)時(shí)性要求高的場景

二、Spring Boot集成WebSocket

2.1 添加依賴

在Spring Boot項(xiàng)目的pom.xml文件中添加WebSocket依賴:

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

如果使用Gradle,在build.gradle中添加:

implementation 'org.springframework.boot:spring-boot-starter-websocket'

2.2 配置WebSocket

創(chuàng)建一個(gè)配置類,用于注冊WebSocket處理程序和配置消息代理:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(StompBrokerRelayRegistration config) {
        config.setApplicationDestinationPrefixes("/app");
        config.setDestinationPrefixes("/topic");
    }
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-endpoint").withSockJS();
    }
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(65536);
        container.setMaxBinaryMessageBufferSize(65536);
        return container;
    }
}

在上述代碼中:

  • @EnableWebSocketMessageBroker 注解啟用WebSocket消息代理。
  • configureMessageBroker方法配置消息代理的前綴,/app用于應(yīng)用程序發(fā)送消息的目的地前綴,/topic用于服務(wù)器發(fā)送消息的目的地前綴。
  • registerStompEndpoints方法注冊WebSocket端點(diǎn),addEndpoint方法指定端點(diǎn)的路徑,withSockJS表示啟用SockJS支持,以提供對不支持WebSocket瀏覽器的兼容。
  • createWebSocketContainer方法配置WebSocket容器的參數(shù),如消息緩沖區(qū)大小。

三、WebSocket常用使用方法

3.1 簡單消息收發(fā)

3.1.1 創(chuàng)建消息實(shí)體類
public class ChatMessage {
    private String sender;
    private String content;
    private MessageType type;
    // 省略構(gòu)造函數(shù)、Getter和Setter方法
    public enum MessageType {
        CHAT, JOIN, LEAVE
    }
}

ChatMessage類用于封裝聊天消息,包含發(fā)送者、消息內(nèi)容和消息類型(聊天、加入、離開)。

3.1.2 創(chuàng)建消息處理類
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class ChatController {
    @MessageMapping("/chat.send")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(ChatMessage chatMessage) {
        return chatMessage;
    }
    @MessageMapping("/chat.join")
    @SendTo("/topic/public")
    public ChatMessage joinChat(ChatMessage chatMessage) {
        chatMessage.setType(ChatMessage.MessageType.JOIN);
        return chatMessage;
    }
}

在上述代碼中:

  • @MessageMapping注解用于映射客戶端發(fā)送的消息路徑,如"/chat.send""/chat.join"。
  • @SendTo注解指定消息發(fā)送的目的地,這里將消息發(fā)送到"/topic/public",所有訂閱該主題的客戶端都能接收到消息。
  • sendMessage方法處理聊天消息的發(fā)送,joinChat方法處理用戶加入聊天的消息。
3.1.3 前端頁面實(shí)現(xiàn)
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Chat</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/stompjs/2.3.3/stomp.min.js"></script>
</head>
<body>
    <input type="text" id="username" placeholder="用戶名">
    <button onclick="connect()">連接</button>
    <div id="chat-window"></div>
    <input type="text" id="message" placeholder="輸入消息">
    <button onclick="sendMessage()">發(fā)送</button>
    <script>
        let socket = new SockJS('/websocket-endpoint');
        let stompClient = Stomp.over(socket);
        function connect() {
            let username = document.getElementById('username').value;
            stompClient.connect({}, function (frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/public', function (message) {
                    let chatWindow = document.getElementById('chat-window');
                    let msg = JSON.parse(message.body);
                    if (msg.type === 'JOIN') {
                        chatWindow.innerHTML += msg.sender + " 加入了聊天
";
                    } else {
                        chatWindow.innerHTML += msg.sender + ": " + msg.content + "
";
                    }
                });
                let joinMessage = {
                    sender: username,
                    content: '',
                    type: 'JOIN'
                };
                stompClient.send("/app/chat.join", {}, JSON.stringify(joinMessage));
            });
        }
        function sendMessage() {
            let message = document.getElementById('message').value;
            let username = document.getElementById('username').value;
            let chatMessage = {
                sender: username,
                content: message,
                type: 'CHAT'
            };
            stompClient.send("/app/chat.send", {}, JSON.stringify(chatMessage));
        }
    </script>
</body>
</html>

前端頁面通過SockJS和StompJS庫與后端建立WebSocket連接,實(shí)現(xiàn)消息的發(fā)送和接收。

3.2 點(diǎn)對點(diǎn)消息發(fā)送

有時(shí)候需要實(shí)現(xiàn)一對一的消息發(fā)送,而不是廣播給所有客戶端??梢酝ㄟ^在@SendTo中指定具體的用戶目的地來實(shí)現(xiàn)。

3.2.1 配置用戶目的地前綴

WebSocketConfig類中添加用戶目的地前綴配置:

@Override
public void configureMessageBroker(StompBrokerRelayRegistration config) {
    config.setApplicationDestinationPrefixes("/app");
    config.setDestinationPrefixes("/topic", "/user");
    config.setUserDestinationPrefix("/user");
}

這里添加了/user作為用戶目的地前綴。

3.2.2 修改消息處理類
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.stereotype.Controller;
@Controller
public class PrivateChatController {
    @MessageMapping("/chat.private")
    public void sendPrivateMessage(SimpMessageHeaderAccessor headerAccessor, ChatMessage chatMessage) {
        String recipient = chatMessage.getRecipient();
        headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
        this.stompMessagingTemplate.convertAndSendToUser(recipient, "/private", chatMessage);
    }
}

在上述代碼中:

  • @MessageMapping("/chat.private")映射處理點(diǎn)對點(diǎn)消息的路徑。
  • SimpMessageHeaderAccessor用于獲取和設(shè)置消息頭信息。
  • stompMessagingTemplate.convertAndSendToUser方法將消息發(fā)送到指定用戶的私有目的地。
3.2.3 前端實(shí)現(xiàn)點(diǎn)對點(diǎn)消息發(fā)送
function sendPrivateMessage() {
    let message = document.getElementById('message').value;
    let username = document.getElementById('username').value;
    let recipient = document.getElementById('recipient').value;
    let chatMessage = {
        sender: username,
        recipient: recipient,
        content: message,
        type: 'CHAT'
    };
    stompClient.send("/app/chat.private", {}, JSON.stringify(chatMessage));
}

前端添加輸入接收者的文本框,并在發(fā)送消息時(shí)指定接收者,實(shí)現(xiàn)點(diǎn)對點(diǎn)消息發(fā)送。

3.3 消息攔截與認(rèn)證

在實(shí)際應(yīng)用中,可能需要對WebSocket消息進(jìn)行攔截和認(rèn)證,確保只有合法用戶才能進(jìn)行通信。

3.3.1 創(chuàng)建消息攔截器
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.messaging.support.MessageHeaderAccessor;
import org.springframework.stereotype.Component;
@Component
public class WebSocketInterceptor implements ChannelInterceptor {
    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
            // 在這里進(jìn)行認(rèn)證邏輯,如檢查Token等
            String token = accessor.getFirstNativeHeader("Authorization");
            if (token == null ||!isValidToken(token)) {
                throw new RuntimeException("認(rèn)證失敗");
            }
        }
        return message;
    }
    private boolean isValidToken(String token) {
        // 實(shí)現(xiàn)具體的Token驗(yàn)證邏輯
        return true;
    }
}

上述代碼創(chuàng)建了一個(gè)WebSocketInterceptor攔截器,在preSend方法中對連接請求進(jìn)行認(rèn)證,檢查請求頭中的Authorization Token是否有效。

3.3.2 注冊攔截器

WebSocketConfig類中注冊攔截器:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.interceptors(new WebSocketInterceptor());
    }
    // 其他配置方法...
}

通過configureClientInboundChannel方法將攔截器注冊到客戶端入站通道,對所有進(jìn)入的消息進(jìn)行攔截處理。

四、不使用接口,基于注解的WebSocket實(shí)現(xiàn)

4.1 實(shí)現(xiàn)思路

在Spring Boot中,除了通過實(shí)現(xiàn)接口的方式處理WebSocket消息,還可以利用注解來簡化開發(fā)過程。通過@ServerEndpoint注解定義WebSocket端點(diǎn),結(jié)合@OnOpen、@OnMessage、@OnClose、@OnError等注解,能夠輕松實(shí)現(xiàn)對WebSocket連接生命周期的監(jiān)聽,以及接收和處理客戶端發(fā)送的數(shù)據(jù)。

4.2 核心代碼實(shí)現(xiàn)

首先,創(chuàng)建一個(gè)WebSocket處理類:

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
@ServerEndpoint("/ws/{userId}")
public class MyWebSocket {
    // 靜態(tài)變量,用來記錄當(dāng)前在線連接數(shù)。應(yīng)該把它設(shè)計(jì)成線程安全的。
    private static int onlineCount = 0;
    // concurrent包的線程安全Set,用來存放每個(gè)客戶端對應(yīng)的MyWebSocket對象。
    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<>();
    // 與某個(gè)客戶端的連接會話,需要通過它來給客戶端發(fā)送數(shù)據(jù)
    private Session session;
    // 接收userId
    private String userId;
    /**
     * 連接建立成功調(diào)用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        webSocketSet.add(this);
        addOnlineCount();
        System.out.println("有新連接加入!當(dāng)前在線人數(shù)為" + getOnlineCount());
    }
    /**
     * 連接關(guān)閉調(diào)用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        subOnlineCount();
        System.out.println("有一連接關(guān)閉!當(dāng)前在線人數(shù)為" + getOnlineCount());
    }
    /**
     * 收到客戶端消息后調(diào)用的方法
     *
     * @param message 客戶端發(fā)送過來的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("來自客戶端" + userId + "的消息:" + message);
        // 群發(fā)消息
        for (MyWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 發(fā)生錯(cuò)誤時(shí)調(diào)用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("發(fā)生錯(cuò)誤");
        error.printStackTrace();
    }
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    public static synchronized void addOnlineCount() {
        MyWebSocket.onlineCount++;
    }
    public static synchronized void subOnlineCount() {
        MyWebSocket.onlineCount--;
    }
}

在上述代碼中:

  • @ServerEndpoint("/ws/{userId}")注解定義了WebSocket的訪問端點(diǎn),{userId}為路徑參數(shù),用于標(biāo)識不同的客戶端。
  • @OnOpen注解的方法在連接建立時(shí)被調(diào)用,用于初始化連接相關(guān)信息,并將當(dāng)前連接對象添加到在線連接集合中。
  • @OnMessage注解的方法在接收到客戶端發(fā)送的消息時(shí)被調(diào)用,實(shí)現(xiàn)了消息的接收和群發(fā)功能。
  • @OnClose注解的方法在連接關(guān)閉時(shí)被調(diào)用,從在線連接集合中移除當(dāng)前連接對象。
  • @OnError注解的方法在發(fā)生錯(cuò)誤時(shí)被調(diào)用,用于處理異常情況。

4.3 前端頁面適配

前端頁面同樣需要進(jìn)行相應(yīng)的修改,以連接基于注解實(shí)現(xiàn)的WebSocket端點(diǎn):

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>基于注解的WebSocket Chat</title>
</head>
<body>
    <input type="text" id="userId" placeholder="用戶ID">
    <button onclick="connect()">連接</button>
    <div id="chat-window"></div>
    <input type="text" id="message" placeholder="輸入消息">
    <button onclick="sendMessage()">發(fā)送</button>
    <script>
        let socket;
        function connect() {
            let userId = document.getElementById('userId').value;
            socket = new WebSocket("ws://localhost:8080/ws/" + userId);
            socket.onopen = function (event) {
                console.log("連接成功");
            };
            socket.onmessage = function (event) {
                let chatWindow = document.getElementById('chat-window');
                chatWindow.innerHTML += "收到消息: " + event.data + "
";
            };
            socket.onclose = function (event) {
                console.log("連接關(guān)閉");
            };
            socket.onerror = function (event) {
                console.log("連接錯(cuò)誤");
            };
        }
         function sendMessage() {
            let message = document.getElementById('message').value;
            if (socket && socket.readyState === WebSocket.OPEN) {
                socket.send(message);
                document.getElementById('chat-window').innerHTML += "發(fā)送消息: " + message + "
";
                document.getElementById('message').value = "";
            } else {
                alert("WebSocket連接未建立或已關(guān)閉");
            }
        }
    </script>
</body>
</html>

4.4 配置WebSocket端點(diǎn)

還需要在Spring Boot中配置WebSocket支持,確保端點(diǎn)被正確注冊:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
@Configuration
public class WebSocketConfig {
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192);
        container.setMaxBinaryMessageBufferSize(8192);
        return container;
    }
}

這種基于注解的實(shí)現(xiàn)方式相比傳統(tǒng)接口方式更加簡潔直觀,通過注解即可完成WebSocket連接的生命周期管理和消息處理。

五、應(yīng)用場景拓展

5.1 實(shí)時(shí)數(shù)據(jù)推送

在股票交易、天氣監(jiān)測等場景中,服務(wù)器需要實(shí)時(shí)向客戶端推送數(shù)據(jù)??梢越Y(jié)合定時(shí)任務(wù)實(shí)現(xiàn):

@Service
public class RealTimeDataService {
    @Autowired
    private SimpMessagingTemplate messagingTemplate;
    @Scheduled(fixedRate = 5000) // 每5秒執(zhí)行一次
    public void pushRealTimeData() {
        // 獲取實(shí)時(shí)數(shù)據(jù)
        StockData stockData = getStockData();
        // 推送給訂閱了實(shí)時(shí)股票信息的客戶端
        messagingTemplate.convertAndSend("/topic/stock", stockData);
    }
    private StockData getStockData() {
        // 模擬獲取股票數(shù)據(jù)
        return new StockData("000001", "平安銀行", 15.68, 0.23);
    }
}

5.2 在線協(xié)作編輯

多個(gè)用戶可以同時(shí)編輯同一個(gè)文檔,實(shí)時(shí)看到彼此的操作:

@MessageMapping("/edit")
@SendTo("/topic/document/{docId}")
public EditOperation handleEdit(@DestinationVariable String docId, EditOperation operation) {
    // 處理編輯操作,更新文檔
    documentService.applyEdit(docId, operation);
    return operation;
}

5.3 游戲?qū)崟r(shí)對戰(zhàn)

在在線游戲中,玩家的操作需要實(shí)時(shí)同步到其他玩家:

@MessageMapping("/game/{roomId}/move")
public void handleGameMove(@DestinationVariable String roomId, MoveAction action) {
    // 更新游戲狀態(tài)
    gameService.updateGameState(roomId, action);
    // 廣播給房間內(nèi)的所有玩家
    messagingTemplate.convertAndSend("/topic/game/" + roomId, action);
}

六、性能優(yōu)化與最佳實(shí)踐

6.1 連接管理

  • 使用連接池管理WebSocket連接,避免頻繁創(chuàng)建和銷毀連接
  • 對長時(shí)間不活躍的連接進(jìn)行心跳檢測和自動(dòng)關(guān)閉
  • 限制單個(gè)客戶端的連接數(shù)量,防止惡意連接

6.2 消息處理優(yōu)化

  • 對高頻消息進(jìn)行合并和批處理,減少網(wǎng)絡(luò)開銷
  • 使用異步處理機(jī)制,避免阻塞主線程
  • 對大消息進(jìn)行分片傳輸,防止消息過大導(dǎo)致的性能問題

6.3 安全加固

  • 使用SSL/TLS加密WebSocket連接,確保數(shù)據(jù)傳輸安全
  • 實(shí)現(xiàn)嚴(yán)格的身份認(rèn)證和權(quán)限控制
  • 對客戶端輸入進(jìn)行過濾和驗(yàn)證,防止XSS和SQL注入攻擊

6.4 監(jiān)控與告警

  • 監(jiān)控WebSocket連接數(shù)、消息吞吐量等指標(biāo)
  • 設(shè)置異常告警機(jī)制,及時(shí)發(fā)現(xiàn)和處理連接異常和性能問題

七、常見問題與解決方案

7.1 跨域問題

  • 配置CORS允許WebSocket端點(diǎn)的跨域訪問
registry.addEndpoint("/websocket-endpoint")
        .setAllowedOrigins("*")
        .withSockJS();

7.2 消息丟失問題

  • 實(shí)現(xiàn)消息確認(rèn)機(jī)制,確保消息可靠傳遞
  • 使用持久化隊(duì)列存儲重要消息,防止服務(wù)器重啟導(dǎo)致消息丟失

7.3 性能瓶頸

  • 分析性能瓶頸點(diǎn),針對性地進(jìn)行優(yōu)化
  • 考慮使用分布式消息隊(duì)列和集群部署提高系統(tǒng)吞吐量

八、總結(jié)

本文從WebSocket的基礎(chǔ)概念出發(fā),詳細(xì)介紹了Spring Boot集成WebSocket的步驟,并重點(diǎn)講解了常用的使用方法,包括簡單消息收發(fā)、點(diǎn)對點(diǎn)消息發(fā)送、消息攔截與認(rèn)證,以及不使用接口而是基于注解的WebSocket實(shí)現(xiàn)方式。同時(shí),還拓展了WebSocket在不同場景下的應(yīng)用,提供了性能優(yōu)化建議和常見問題解決方案。

通過這些方法,開發(fā)者可以根據(jù)實(shí)際需求,靈活運(yùn)用WebSocket在Spring Boot應(yīng)用中實(shí)現(xiàn)高效的實(shí)時(shí)通信功能。在實(shí)際項(xiàng)目中,還可以結(jié)合更多的Spring Boot特性和業(yè)務(wù)邏輯,進(jìn)一步擴(kuò)展和優(yōu)化WebSocket的應(yīng)用,打造出更強(qiáng)大、更實(shí)用的實(shí)時(shí)應(yīng)用程序。

以上補(bǔ)充內(nèi)容完善了基于注解的WebSocket實(shí)現(xiàn)方案,并新增了應(yīng)用場景拓展、性能優(yōu)化等實(shí)用內(nèi)容。如需進(jìn)一步深入探討某個(gè)主題,或需要其他補(bǔ)充,請隨時(shí)告知。

到此這篇關(guān)于Spring Boot中WebSocket常用使用方法詳解的文章就介紹到這了,更多相關(guān)springboot websocket使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論