首先我想告诉你一堆不起作用的教程:
Spring Boot WebSocket STOMP SockJS 示例
这些教程的内容如下:
var socket = new SockJS('/chat');
var socket = new SockJS('/ws');
var socket = new SockJS('/gs-guide-websocket');
let sock = new SockJS("http://localhost:8080/stomp");
我的印象是,如果没有“localhost”,那么它会尝试连接同一域。这意味着
/chat
、/ws
等中的前端位于 localhost:8080
上,后端服务器也是如此。但这对我不起作用,因为我的前端是 localhost:5173
,我的后端是 localhost:8080
,所以我必须告诉它去哪里。我证实了我的怀疑,因为当我输入 GET http://localhost:5173/stomp/info?t=1680631128497 404
时,我得到了 var socket = new SockJS('/stomp');
。所以至少我知道我的一些代码是正确的。
我不知道我的预期结果是什么,因为(1)我是 websockets 的新手(2)我是 Spring Boot 的新手,(3)我是 SockJS 的新手。但我希望触发我的日志语句之一,以便我知道已到达代码,或者从后端发送的消息记录在客户端上,反之亦然。
我的实际结果是:
GET http://localhost:8080/stomp/info?t=1680630627152 404
此失败消息让我认为我需要一个
/stomp/info
端点。然而,所有教程都没有提到 /info
端点。所以我不需要,否则他们都会这么说。
这是我的前端代码:
import Stomp from "stompjs";
function connect() {
var socket = new SockJS('http://localhost:8080/stomp');
// the code fails around here
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function(messageOutput) {
showMessageOutput(JSON.parse(messageOutput.body));
});
});
}
// later...
<svelte:head>
<title>Chat WebSocket</title>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<!-- <script src="resources/js/stomp.js"></script> -->
</svelte:head>
然后在 Spring Boot 中:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp")
.setAllowedOrigins("http://localhost:5173").withSockJS();
}
}
聊天控制器:
@Controller
public class ChatController {
@MessageMapping("/cat")
@SendTo("/topic/public")
public ChatMessage hatResponse(@Payload final ChatMessage chat) {
System.out.println("hat");
return chat;
}
}
这里还有另外一堆使用 SockJS 不起作用的方法:
/app/chat
:var socket = new SockJS('http://localhost:8080/app/cat');
给出GET http://localhost:8080/app/cat/info?t=1680631745245 404
/app/stomp
:var socket = new SockJS('http://localhost:8080/app/stomp');
给出GET http://localhost:5173/stomp/info?t=1680631712894 404
/stomp
:var socket = new SockJS('http://localhost:8080/stomp');
给出GET http://localhost:5173/stomp/info?t=1680631676987 404
/cat
:var socket = new SockJS('http://localhost:8080/cat');
给出GET http://localhost:8080/cat/info?t=1680631770418 404
所有教程都没有提到 /info 端点。如果 /info 端点是必需的,为什么教程没有提到它?四连胜建立了强大的格局。所以显然不是这个。
我不知道该怎么办。 Java、Spring Boot 和 Websockets 对我来说都是新事物,所以一下子需要了解很多内容。
编辑:更多研究
没有 SockJS 的 Spring 启动 Websocket 说:
“如果有人想使用 SockJS 客户端进行连接,他们可以使用...进行连接
var socket = new SockJS('http://localhost:8080/test');
stompClient = Stomp.over(socket);
”
这意味着问题一定出在我的代码中的其他地方,因为发布者是按照我的方式做的。但到哪里去找问题呢?
编辑 2023 年 4 月 16 日:以下是我找到的一些研究链接
Webpack 开发服务器 sockjs-node 返回 404 错误
我认为这些链接对我的 Spring Boot 方面没有帮助。
2023 年 4 月 16 日第二次编辑:这里的链接确实有帮助!
您能解决这个问题吗?您如何使用 springboot 3 的链接 web.xml 解决方案来解决它?