reactjsspring-bootwebsocketstompstompjs

Spring @SubscribeMapping being called


i am trying to make a webpage for multiplayer games similar to the jackbox party pack series.

I want to do this by creating sessions/rooms which are identified by a randomly generated 4 letter sequence.I am using spring as a backend and react.js with stomp-js as a frontend.

Now for my prototype i am making a chat application. And i want to send the whole chat log when a user subscribes to the the session. The url the client subscribes to should be "/topic/{roomCode}".

my spring SocketConfiguration looks like this

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {

    registry.addEndpoint("/stomp-endpoint").setAllowedOrigins("*");
    registry.addEndpoint("/stomp-endpoint").setAllowedOrigins("*").withSockJS();
}

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {

    registry.enableSimpleBroker("/topic");
    registry.setApplicationDestinationPrefixes("/app");
}

To do this i've got a controler in spring that has this method:

@SubscribeMapping("/topic/{gameCode}")
public Message joinGame(@DestinationVariable String gameCode){

    System.out.println("This method has been called");
    return sessions.joinGame(gameCode);
}

But this method never gets called. I have confirmed this using the debugger in inteliJ. I can send messages fine just the subscribtion mapping doesn't work. Just to be sure though here is the method used to send messages to the clients:

@MessageMapping("/{gameCode}")
@SendTo("/topic/{gameCode}")
public Message test(Message message, @DestinationVariable String gameCode ){

    Game game = sessions.get(gameCode).getGame();
    return game.changeStatus(message);
}

In my react.js app i've got this bit of code for connecting and receiving/sending messages: (please don't judge me for using class based components)

initializeChat() {

    const client = new Client({

        brokerURL: "ws://localhost:8080/stomp-endpoint",
        debug: (str) => console.log(str)
    })

    client.onConnect = this.subscribe.bind(this, client)
    client.activate()
    return client
}

subscribe(client){

    let sessionCode = this.props.session.code
    client.subscribe("/topic/"+ sessionCode,this.receiveMessage)
}

sendMessage(e) {

    e.preventDefault()
    let sessionCode = this.props.session.code;
    let message = document.getElementById("message").value;
    this.state.connection.publish({ destination: '/topic/'+sessionCode, body: message });
}

receiveMessage(message) {

    let appendMessage = message.body+"<br>"
    let history = document.getElementById("history")
    history.append(appendMessage)
}

I've tried to switch the subscribe mapping to "/{gamecode}" which yielded the same result.


Solution

  • So i found a fix but don't know why this fixes it so if anyone can pitch in for that i would wecome it.

    adding "/topic" to the ApplicationDestinationPrefixes fixed it. My config looks like this now:

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
    
        registry.addEndpoint("/stomp-endpoint").setAllowedOrigins("*");
        registry.addEndpoint("/stomp-endpoint").setAllowedOrigins("*").withSockJS();
    }
    
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
    
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app","/topic");
        
    }