Search code examples
spring-bootwebsocketstomp

Stomp WebSocket subscribe to two different topics


I have one websocket server and one websocket client both in Java. The websocket server has this:

@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(final HelloMessage message) throws Exception {
    Thread.sleep(1000); // simulated delay
    return new Greeting("Hello, " + message.getName() + "!");
}

And in the Java WebSocket client I have the following in my StompSessionHandler.afterConnected:

session.subscribe("/topic/greetings", stompFrameHandler)

Then, I am able to communicate between the two by, the client sending a message to the server path "hello" and then since the client is subscribed to "topic/greetings", I am also to handle the response with my stompFrameHandler.

But I am wondering if it is possible for a client to subscribe to two different "channels", so something like this in StompSessionHandler.afterConnected:

session.subscribe("/topic/greetings", greetingsFrameHandler)
session.subscribe("/topic/farewell", farewellFrameHandler)

Because I tried and I can only receive events from topic/greetings, but not for topic/farewell. I do not know if this is important, but to trigger a farewell event I make a rest call to the websocket server:

@PostMapping(value = "/sendFarewellEvent", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@SendTo("/topic/farewell")
public Farewell farewell(@RequestBody final Farewell farewell) throws Exception {
    Thread.sleep(1000); // simulated delay
    return farewell;
}

Solution

  • I am wondering if it is possible for a client to subscribe to two different "channels"

    Yes, that works.

    to trigger a farewell event I make a rest call to the websocket server

    Just combining @PostMapping with @SendTo does not work as you would wish. The handlers for @PostMapping (org.springframework.servlet.*) are different than those handling the @MessageMapping (org.springframework.messaging.*) and don't handle the @SendTo annotation in any special way.

    You may want to use SimpMessagingTemplate to send the message explicitly: How to call @SendTo from Normal Request Call i.e @RequestMapping