使用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)"; } }
排查关键点
跨域问题
如果前端页面从非8080端口加载(比如本地静态服务器),会触发跨域限制。修改WebSocket配置类的端点注册,添加跨域允许:@Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/game-websocket").setAllowedOrigins("*"); // 生产环境需指定具体域名,避免全开放 }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)"; }STOMP publish方法参数格式错误
StompJs v7的publish方法要求传入配置对象,而非三个独立参数。修改sendID函数:function sendID(){ stompClient.publish({ destination: "/app/provideSession", body: "kevin" }); }检查Spring组件扫描范围
确保WebSocketConfig所在包被Spring Boot的组件扫描覆盖(默认扫描启动类所在包及子包),若不在同一包下,需添加@ComponentScan指定包路径。查看浏览器控制台详细错误
点击控制台中WebSocket连接失败的报错条目,查看具体原因(如404表示端点不存在、CORS表示跨域、握手失败表示协议不匹配等),针对性解决。
内容的提问来源于stack exchange,提问作者Tired8296
相关产品推荐
相关产品推荐

