You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用STOMP.js连接Spring Boot WebSocket失败问题求助

问题排查:Spring Boot WebSocket + STOMP.js 连接失败

激活StompJs.Client对象时,浏览器控制台报错:

WebSocket connection to 'ws://localhost:8080/game-websocket' failed: https://cdn.jsdelivr.net/npm/@stomp/stompjs@7.0.0/bundles/stomp.umd.min.js

以下是相关代码及排查方案:


前端HTML代码

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>Battleships</title>
        <link href="/static/GameDesign.css" rel="stylesheet">
        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@stomp/stompjs@7.0.0/bundles/stomp.umd.min.js"></script>
        <script src="/static/GameScript.js"></script>

    </head>

    <body>

        <!-- 生成当前会话的敌方棋盘(隐藏),包含100个带对应ID的按钮,从左下角开始按行计数 -->
        <script>
            document.write("<form><table>");
            for(var i=9; i>=0; i--){
                document.write("<tr>");
                for(var k=0; k<10; k++){
                    document.write("<td><button type=\"submit\" id=\"e" + k + i + "\"></button></td>");
                }
                document.write("</tr>");
            }
            document.write("</table></form>");
        </script>

        <!-- 生成当前会话的己方棋盘,包含100个带对应ID的div元素,从左下角开始按行计数 -->
        <script>
            document.write("<table>");
            for(var i=9; i>=0; i--){
                document.write("<tr>");
                for(var k=0; k<10; k++){
                    document.write("<td><div id=\"o" + k + i + "\"></div></td>");
                }
                document.write("</tr>");
            }
            document.write("</table>");
        </script>

    </body>

</html>

GameScript.js代码

const stompClient = new StompJs.Client({
    brokerURL: 'ws://localhost:8080/game-websocket'
});

function connect(){
    stompClient.activate();
}

function sendID(){
     stompClient.publish("/app/provideSession", {}, "kevin");
}

stompClient.onConnect = (frame) => {
    stompClient.subscribe("/queue/sessionResponse", (message) => {
        console.log(message);
    });
}

$(function () {
    $("form").on('submit', (e) => e.preventDefault());
    $( "#e00" ).click(() => connect());
    $( "#e99" ).click(() => sendID());
});

WebSocket配置类

package com.md.battleships;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/game-websocket");
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.setApplicationDestinationPrefixes("/app");
        config.enableSimpleBroker("/queue");
    }
}

Controller类

package com.md.battleships;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class GameController {

    @MessageMapping("/provideSession")
    @SendTo("/sessionResponse")
    public String handshake (String session) throws Exception{
        System.out.println(session);
        return "kevoon (Entwicklung von Kevin)";
    }
}

排查关键点

  1. 跨域问题
    如果前端页面从非8080端口加载(比如本地静态服务器),会触发跨域限制。修改WebSocket配置类的端点注册,添加跨域允许:

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/game-websocket").setAllowedOrigins("*"); // 生产环境需指定具体域名,避免全开放
    }
    
  2. Controller的@SendTo路径错误
    配置类中启用了/queue作为简单消息代理,但Controller的@SendTo("/sessionResponse")缺少/queue前缀,与前端订阅路径不匹配。修改为:

    @MessageMapping("/provideSession")
    @SendTo("/queue/sessionResponse")
    public String handshake (String session) throws Exception{
        System.out.println(session);
        return "kevoon (Entwicklung von Kevin)";
    }
    
  3. STOMP publish方法参数格式错误
    StompJs v7的publish方法要求传入配置对象,而非三个独立参数。修改sendID函数:

    function sendID(){
         stompClient.publish({
             destination: "/app/provideSession",
             body: "kevin"
         });
    }
    
  4. 检查Spring组件扫描范围
    确保WebSocketConfig所在包被Spring Boot的组件扫描覆盖(默认扫描启动类所在包及子包),若不在同一包下,需添加@ComponentScan指定包路径。

  5. 查看浏览器控制台详细错误
    点击控制台中WebSocket连接失败的报错条目,查看具体原因(如404表示端点不存在、CORS表示跨域、握手失败表示协议不匹配等),针对性解决。


内容的提问来源于stack exchange,提问作者Tired8296

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:13:14