15. 实时数据-SpringBoot集成WebSocket

文章目录

  • 前言
    • 一、添加依赖(Maven)
    • [二、配置 WebSocket](#二、配置 WebSocket)
      • [1. 创建 WebSocket 配置类](#1. 创建 WebSocket 配置类)
      • [2. 实现 WebSocket 处理器](#2. 实现 WebSocket 处理器)
    • [三、前端测试(HTML + JS)](#三、前端测试(HTML + JS))
    • [四、启动类(标准 Spring Boot 启动类)](#四、启动类(标准 Spring Boot 启动类))
    • [五、可选:使用 STOMP over WebSocket(更高级)](#五、可选:使用 STOMP over WebSocket(更高级))
    • 六、注意事项

前言

SpringBoot集成WebSocket

  在 Spring Boot 中集成 WebSocket 可以实现服务器与客户端之间的双向通信,常用于实时消息推送、聊天室、在线通知等场景。


一、添加依赖(Maven)

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

二、配置 WebSocket

1. 创建 WebSocket 配置类

java 复制代码
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 {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 注册处理器,允许跨域访问
        registry.addHandler(myWebSocketHandler(), "/websocket")
                .setAllowedOrigins("*"); // 生产环境应限制具体域名
    }

    public MyWebSocketHandler myWebSocketHandler() {
        return new MyWebSocketHandler();
    }
}

2. 实现 WebSocket 处理器

java 复制代码
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 MyWebSocketHandler extends TextWebSocketHandler {

    // 存储所有连接的会话
    private static final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(session.getId(), session);
        System.out.println("新连接: " + session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到消息: " + payload);

        // 广播给所有连接的客户端
        for (WebSocketSession s : sessions.values()) {
            if (s.isOpen()) {
                s.sendMessage(new TextMessage("Echo: " + payload));
            }
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session.getId());
        System.out.println("连接关闭: " + session.getId());
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        sessions.remove(session.getId());
        session.close(CloseStatus.SERVER_ERROR);
        System.out.println("连接异常: " + session.getId());
    }
}

三、前端测试(HTML + JS)

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket 测试</title>
</head>
<body>
    <input type="text" id="message" placeholder="输入消息">
    <button onclick="sendMessage()">发送</button>
    <div id="output"></div>

    <script>
        const ws = new WebSocket('ws://localhost:8080/websocket');

        ws.onopen = function(event) {
            console.log('连接已建立');
        };

        ws.onmessage = function(event) {
            document.getElementById('output').innerHTML += '<p>' + event.data + '</p>';
        };

        ws.onclose = function(event) {
            console.log('连接已关闭');
        };

        function sendMessage() {
            const msg = document.getElementById('message').value;
            ws.send(msg);
        }
    </script>
</body>
</html>

四、启动类(标准 Spring Boot 启动类)

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebsocketApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebsocketApplication.class, args);
    }
}

五、可选:使用 STOMP over WebSocket(更高级)

如果你需要更复杂的协议(如订阅/发布、路径匹配、安全认证等),可以考虑使用 STOMP 协议,Spring Boot 对其有良好支持。


六、注意事项

  • setAllowedOrigins("*") 在生产环境中应替换为具体的可信域名。
  • WebSocket 连接是长连接,注意资源释放和异常处理。
  • 若部署在 Nginx 或云服务后,需确保代理支持 WebSocket(设置 Upgrade 和 Connection 头)。

如需基于注解(@ServerEndpoint)的方式(使用原生 Java EE WebSocket API),也可以配合 spring-boot-starter-websocket 使用,但 Spring 推荐使用 WebSocketHandler 或 STOMP 方式。


本文的引用仅限自我学习如有侵权,请联系作者删除。
参考知识
<>


相关推荐
上进小菜猪6 小时前
把 KES 集群交给 Kubernetes 的九十天:一个 DBA 的试用实录
后端
两点王爷7 小时前
PostgreSQL 常用 SQL 语句与 GIS 相关函数详解
数据库·后端
考虑考虑8 小时前
Springboot环境变量占位符语法
spring boot·后端·spring
步行cgn9 小时前
Spring 基于 XML 的自动装配:byName 详解
java·后端·spring
边境悍匪11 小时前
蜗牛学苑 Java 智能体学习 Day42|项目周开发技术汇总 1 思维导图复盘
java·开发语言·spring boot·学习·spring
RISCV_Explorer11 小时前
RISC-V启动与运行时规范机制解析——BRS约定、HSM多核启动与设备树要求
后端·risc-v
星栈独行11 小时前
ADK-Rust 是什么?Rust 生态新一代 AI Agent 开发套件
人工智能·后端·rust
JavaGuide12 小时前
对标 MinIO!全新一代分布式文件系统正式发布
前端·后端
xcl092512 小时前
本地电竞服务交易系统架构设计与实战:从同城匹配到订单履约
java·spring boot
用户83562907805112 小时前
使用 Python 将 DOCX 转换为 Markdown
后端·python