【全栈进阶】Spring Boot 整合 WebSocket 实战:从实时告警到金融行情推送

【全栈进阶】Spring Boot 整合 WebSocket 实战:从实时告警到金融行情推送

一、 为什么要使用 WebSocket?

传统的 HTTP 协议是"一问一答"模式,只能由客户端发起。但在许多高性能场景下,我们需要服务器能"主动推"数据给客户端。

  • 场景 A(实时告警):运维监控系统检测到服务器 CPU 过载,需要瞬间在管理员屏幕上弹出红框。
  • 场景 B(金融行情):股票或数字货币交易平台,价格每秒波动几十次,用户需要无延迟看到跳动的数字。

二、 Spring Boot 快速上手

1. 添加依赖

pom.xml 中引入 Web 和 WebSocket 的 Starter:

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

2. 配置中心:注册 WebSocket

我们需要一个配置类来开启 WebSocket 支持,并注册 Endpoint。

java 复制代码
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        // 注册路径为 /ws/system 的处理器,并允许跨域
        registry.addHandler(new SystemNotificationHandler(), "/ws/system")
                .setAllowedOrigins("*");
    }
}

3. 核心处理器:SystemNotificationHandler

这里负责处理连接的建立、消息的接收以及最重要的主动推送

java 复制代码
@Component
public class SystemNotificationHandler extends TextWebSocketHandler {

    // 保存所有活跃的会话
    private static final Set<WebSocketSession> sessions = new CopyOnWriteArraySet<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.add(session);
        System.out.println("新连接建立: " + session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 接收客户端消息(如:心跳检测)
        System.out.println("收到消息: " + message.getPayload());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        sessions.remove(session);
    }

    // 自定义方法:向所有在线用户广播告警
    public static void broadcastAlert(String alertMsg) {
        for (WebSocketSession session : sessions) {
            if (session.isOpen()) {
                try {
                    session.sendMessage(new TextMessage(alertMsg));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

三、 实战场景改版:金融行情实时推送

在金融交易系统中,我们通常会开启一个后台线程或定时任务,持续获取最新的行情数据,并推送给所有已连接的交易员。

java 复制代码
@Component
public class StockPriceSimulator {

    /**
     * 模拟每隔 1 秒推送一次股票价格更新
     */
    @Scheduled(fixedRate = 1000)
    public void pushStockPrices() {
        double price = 100 + Math.random() * 10;
        String jsonPayload = String.format("{\"symbol\": \"AAPL\", \"price\": %.2f}", price);
        
        // 调用 Handler 的广播方法
        SystemNotificationHandler.broadcastAlert(jsonPayload);
    }
}

四、 前端 JS 客户端实现

前端代码无需引入插件,直接使用 HTML5 标准 API 即可:

js 复制代码
// 连接到服务端
const socket = new WebSocket("ws://localhost:8080/ws/system");

// 接收服务端推送的实时行情或系统告警
socket.onmessage = function(event) {
    const data = JSON.parse(event.data);
    console.log("收到推送:", data);
    
    // 如果是告警,则显示通知弹窗
    if(data.price > 105) {
        showToast("价格预警:苹果股价已超过 $105!");
    }
};

socket.onopen = () => console.log("连接已开启");
socket.onclose = () => console.log("连接已断开");

五、 总结与进阶建议

  1. 心跳机制 :为了防止网络波动或防火墙强制断开长连接,建议前端每 30 秒向后端发送一次 Ping 包,后端回应 Pong
  2. 分布式部署 :如果你的应用有多个节点,必须引入 Redis Pub/Sub。当 A 节点触发广播时,通过 Redis 通知 B、C 节点,让它们也向各自连接的客户端推送。
  3. 安全性 :不要在 URL 中明文传输敏感信息,建议在 HandshakeInterceptor 中拦截请求并校验 Token。

作者: [你的名字]

相关推荐
张3蜂2 小时前
java springboot2.0 api ;.netcore8 api ;python GunicornAPI ,哪种更强?请从多个维度,对比分析
java·python·.netcore
市场部需要一个软件开发岗位2 小时前
一个无人机平台+算法监督平台的离线部署指南
java·python·算法·bash·无人机·持续部署
凤山老林2 小时前
SpringBoot + MyBatis-Plus 如何高效实现数据变更记录
java·spring boot·mybatis
Vivienne_ChenW2 小时前
Spring 事件驱动用法总结
java·开发语言·spring boot·spring
Leinwin2 小时前
Moltbot 部署至 Azure Web App 完整指南:从本地到云端的安全高效跃迁
后端·python·flask
毕设源码-邱学长2 小时前
【开题答辩全过程】以 基于Springboot个人健康运动系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
愿你天黑有灯下雨有伞2 小时前
Spring Boot + FastExcel:打造完美的导入校验功能
java·spring boot·后端
Rainly20002 小时前
java原生实现企业级spring batch数据迁移
java·spring·batch