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 方式。


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


相关推荐
han_hanker4 小时前
springboot 封装的比较好的 统一的返回类型 工具类
java·spring boot·后端
韩立学长4 小时前
基于Springboot流浪动物救助系统cqy142wz(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
怪只怪满眼尽是人间烟火4 小时前
springboot数据上链FISCO BCOS
java·spring boot·后端
没什么本事5 小时前
Springboot CGLIB 代理对象问题
java·spring boot·spring
Javatutouhouduan5 小时前
SpringBoot整合reids之JSON序列化文件夹操作
java·spring boot·spring·bootstrap·html·后端开发·java架构师
曲莫终5 小时前
springboot集成h2内存数据库运行测试用例
数据库·spring boot·测试用例
她说..5 小时前
Spring AOP场景5——异常处理(附带源码)
java·数据库·后端·spring·springboot·spring aop
BingoGo5 小时前
PHP 值对象实战指南:避免原始类型偏执
后端·php
JaguarJack5 小时前
PHP 值对象实战指南:避免原始类型偏执
后端·php