0

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 info 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!

Spring Websocket and 404 status on connection

plutownium
  • 1,220
  • 2
  • 9
  • 23

0 Answers0