认识使用SpringBoot的WebSocket之前,你要对socket(网络套接字)有一个基本的概念,这部分可以看一看Java自身是如何使用它并使用它的 Java的网络套接字

当明白了socket是什么之后,代码层面就很简单了,下面用一个聊天室的例子实现

首先SpringBoot中需要引入WebSocket的依赖

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

随后,创建WebSocket连接处理类

package com.wy.controller;
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.List;
import java.util.concurrent.CopyOnWriteArrayList;
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
    // 使用写时复制的list保障多套接字时的线程安全,如果你的连接人数变化比较频繁,就应该使用ConcurrentHashMap以id为key,遍历values方法拿到快照,就和CopyOnWriteArrayList一个实现思路了,不过性能偏写
    // 如果你想要一个兼容的方案,那只能是麻烦一点,建立一个普通的list,读写的时候都加锁,不过读的时候 new 一个新集合复用旧数据后立马放开锁
    private static final List sessions = new CopyOnWriteArrayList<>();
    /**
     * 一个新的连接创建时,干什么
     * 这里将会话连接对象放在服务端的集合中,并给这个会话返回一个连接成功的消息
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
        System.out.println("新连接建立: " + session.getId());
        session.sendMessage(new TextMessage("连接成功! 你的ID: " + session.getId()));
    }
    /**
     * 服务端收到来着连接端的消息,干什么
     * 这里发送给所有连接会话
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到消息: " + payload + " from " + session.getId());
        // 广播消息给所有连接的客户端
        for (WebSocketSession webSocketSession : sessions) {
            if (webSocketSession.isOpen()) {
                webSocketSession.sendMessage(new TextMessage(
                        "用户 " + session.getId().substring(0, 8) + ": " + payload
                ));
            }
        }
    }
    /**
     * 连接对话断开时干什么
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        System.out.println("连接关闭: " + session.getId());
    }
}

随后用这个处理类去建立一个配置类

package com.wy.config;
import com.wy.controller.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
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 {
    @Autowired
    private MyWebSocketHandler myWebSocketHandler;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, "/websocket")
                .setAllowedOriginPatterns("*");//响应头中允许所有域名跨域 也可以使用setAllowedOrigins直接指定明确的来源域名
    }
}

有了上面两个,后端的准备就结束了,随后前端使用原生WebSocket连接就可以了

<!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>WebSocket 聊天室</title>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
          <style>
            * {
            
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            }
            body {
            
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
            }
            .chat-container {
            
            width: 100%;
            max-width: 800px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
            overflow: hidden;
            display: flex;
            flex-direction: column;
            height: 600px;