Search code examples
springwebsocketstompspring-websocket

Multiple rooms in Spring using STOMP


Is it possible to create rooms with STOMP and Spring 4? Socket.IO has rooms built in, so I'm wondering if Spring has this

My code at the moment:

@MessageMapping("/room/greet/{room}")
@SendTo("/room/{room}")
public Greeting greet(@DestinationVariable String room, HelloMessage message) throws Exception {
    return new Greeting("Hello, " + room + "!");
}

It would be ideal to have @SendTo("/room/{room}")

however, I am limited to:

@SendTo("/room/room1") 
@SendTo("/room/room2")
@SendTo("/room/room3") 

etc...which is VERY VERY unideal

The client is:

stompClient.subscribe('/room/' + roomID, function(greeting){
    showGreeting(JSON.parse(greeting.body).content);
});

where roomID can be room1, room2, or room3... What If I want more rooms? It feels like such a pain right now


Solution

  • It looks like this "room" feature is actually a publish/subscribe mechanism, something achieved with topics in Spring Websocket support (see STOMP protocol support and destinations for more info on this).

    With this example:

    @Controller
    public class GreetingController {
    
      @MessageMapping("/room/greeting/{room}")
      public Greeting greet(@DestinationVariable String room, HelloMessage message) throws Exception {
        return new Greeting("Hello, " + message.getName() + "!");
      }
    
    }
    

    If a message is sent to "/room/greeting/room1", then the return value Greeting will be automatically sent to "/topic/room/greeting/room1", so the initial destination prefixed with "/topic".

    If you wish to customize the destination, you can use @SendTo just like you did, or use a MessagingTemplate like this:

    @Controller
    public class GreetingController {
    
      private SimpMessagingTemplate template;
    
      @Autowired
      public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
      }
    
      @MessageMapping("/room/greeting/{room}")
      public void greet(@DestinationVariable String room, HelloMessage message) throws Exception {
        Greeting greeting = new Greeting("Hello, " + message.getName() + "!");
        this.template.convertAndSend("/topic/room/"+room, greeting);  
      }
    
    }
    

    I think taking a quick look at the reference documentation and some useful examples, such as a portfolio app and a chat app should be useful.