First I want to tell you about a bunch of tutorials that don't work:
Using WebSocket to build an interactive web application
Getting Started with Spring WebSockets in Java
Spring Boot WebSocket STOMP SockJS Example
Intro to WebSockets with Spring
These tutorials say things like:
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");
My impression is that, if there is no "localhost", then it's trying to connect on the same domain. Meaning the frontend in /chat
, /ws
etc are on localhost:8080
and so is the backend server. But that doesn't work for me because my frontend is localhost:5173
and my backend is localhost:8080
so I have to tell it where to go. I confirm my suspicion because I get GET http://localhost:5173/stomp/info?t=1680631128497 404
when I put var socket = new SockJS('/stomp');
. So at least I know a bit of my code is right.
I don't know what my expected result is, because (1) I am new to websockets (2) I am new to Spring Boot and (3) I am new to SockJS. But I want one of my log statements to be triggered so I know the code was reached, or for a message sent from the backend to be logged on the client, or vice versa.
My actual result is that I get: GET http://localhost:8080/stomp/info?t=1680630627152 404
This failure message makes me think I need a /stomp/info
endpoint. Yet none of the tutorials mention a /info
endpoint. So I don't need one, or else they'd all say that.
Here is my frontend code:
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>
Then in 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();
}
}
The chat controller:
@Controller
public class ChatController {
@MessageMapping("/cat")
@SendTo("/topic/public")
public ChatMessage hatResponse(@Payload final ChatMessage chat) {
System.out.println("hat");
return chat;
}
}
Here's another bunch of ways to use SockJS that don't work:
/app/chat
: var socket = new SockJS('http://localhost:8080/app/cat');
gives GET http://localhost:8080/app/cat/info?t=1680631745245 404
/app/stomp
: var socket = new SockJS('http://localhost:8080/app/stomp');
gives GET http://localhost:5173/stomp/info?t=1680631712894 404
/stomp
: var socket = new SockJS('http://localhost:8080/stomp');
gives GET http://localhost:5173/stomp/info?t=1680631676987 404
/cat
: var socket = new SockJS('http://localhost:8080/cat');
gives GET http://localhost:8080/cat/info?t=1680631770418 404
none of the tutorials mention a /info endpoint. If the /info endpoint is a requirement, why don't the tutorials mention it? Four in a row establishes a strong pattern. So it obviously isn't this.
I don't know what to do. Java, Spring Boot, and Websockets are all new to me, so this is a lot to chew all at once.
Edit: more research
Spring boot Websocket without SockJS says:
"If someone wants to use SockJS client to connect, they can connect using...
var socket = new SockJS('http://localhost:8080/test');
stompClient = Stomp.over(socket);
"
This means the problem must be elsewhere in my code, since the poster was doing it the way I do. But where to look for the problem?
edit apr 16 2023: Here are some research links I found
Webpack dev server sockjs-node returns 404 error
sockjs-node/info? 404 (Not Found)
I think these links don't help me with the spring boot side of the equation.
2nd edit apr 16 2023: here's a link that does help!