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.
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");
}