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


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


相关推荐
上进小菜猪13 小时前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
韩师傅14 小时前
前端开发消亡史:AI也无法掩盖没有设计创造力的真相
前端·人工智能·后端
栈与堆15 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
superman超哥15 小时前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历
1二山似15 小时前
crmeb多商户启动swoole时报‘加密文件丢失’
后端·swoole
马卡巴卡15 小时前
Java CompletableFuture 接口与原理详解
后端
*才华有限公司*15 小时前
RTSP视频流播放系统
java·git·websocket·网络协议·信息与通信
神奇小汤圆15 小时前
Java线程协作工具:CountDownLatch 、CyclicBarrier、Phaser、Semaphore 、Exchanger
后端
gelald15 小时前
ReentrantLock 学习笔记
java·后端
计算机学姐16 小时前
基于SpringBoot的校园资源共享系统【个性化推荐算法+数据可视化统计】
java·vue.js·spring boot·后端·mysql·spring·信息可视化