Search code examples
spring-bootsocketswebsocketspring-websocketstomp

Why isnt my sockets onsubscribe event getting used?


I am using java springboot with maven in order to get the spring boot starter socket package. My clients are using angular with stompjs and sockjs-client. I am trying to set up a simple web socket application that allows for multiple rooms based on a roomId. When a client joins a room they should receive the last five messages sent in that room.

My Springboot app has three classes, the basic Application.java that I use to run the app, a web socket config class and a web socket controller:

@Controller
public class WebSocketController {
    private final SimpMessagingTemplate template;

    @Autowired
    WebSocketController(SimpMessagingTemplate template){
        this.template = template;
    }

    @MessageMapping("/meeting/{roomId}")
    private void sendMessageTpPrivateRoom(
            String message, 
            @DestinationVariable String roomId
    ) throws IOException {
        System.out.println("message sent to: " + roomId);
        this.template.convertAndSend("/meeting/" + roomId, message);
        addToHistory(roomId, message);
    }

    @SubscribeMapping("/meeting/{roomId}")
    public String chatInit(@DestinationVariable String roomId) {
        System.out.println("Someone joined room: " + roomId);
        return getLastFiveMessages(roomId);
    }
}
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration
        extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/socket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app")
                .enableSimpleBroker("/meeting");
    }
}

my clients are subscribing to the socket like so:

stompClient.subscribe(`app/meeting/${roomId}`, (message) => {
    if (message.body) {
        console.log(message.body);
        messages += '<br>' + message.body;
    }
});

and sending messages like so:

this.stompClient.send(`/app/meeting/${this.roomId}` , {}, message);

The message sending and handling is working great, when I set up three clients, two in room one, and one in room two, the room two messages are not being seen in room one and the room one messages are seen by both clients.

However the on subscribe event is not firing no matter what room I join. It is very necessary that when a client joins room one, they should receive some sort of history of that room. Any advice as to why my SubscribeMapping method is not being triggered when a client subscribes to the room?


Solution

  • The /meeting part will be implicitly added to URL you provide when subscribing. So your mapping will look like this:

        @SubscribeMapping("/${roomId}")
        public String chatInit(@DestinationVariable String roomId) {
            System.out.println("Someone joined room: " + roomId);
            return getLastFiveMessages(roomId);
        }
    

    Source: https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/websocket.html