How can I send a message on connect event (SockJS, STOMP, Spring)?
sockjs, spring, spring-websocket
Solution
If you just want to send a message to the client upon connection, use an appropriate ApplicationListener:
@Component
public class StompConnectedEvent implements ApplicationListener<SessionConnectedEvent> {
private static final Logger log = Logger.getLogger(StompConnectedEvent.class);
@Autowired
private Controller controller;
@Override
public void onApplicationEvent(SessionConnectedEvent event) {
log.debug("Client connected.");
// you can use a controller to send your msg here
}
}
Problem
I am connection through SockJS over STOMP to my Spring backend. Everything work fine, the configuration works well for all browsers etc. However, I cannot find a way to send an initial message. The scenario would be as follows: - The client connects to the topic ``` function connect() { var socket = new SockJS('http://localhost:8080/myEndpoint'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/topic/notify', function(message){ showMessage(JSON.parse(message.body).content); }); }); } ``` and the backend config looks more or less like this: ``` @Configuration @EnableWebSocketMessageBroker public class WebSocketAppConfig extends AbstractWebSocketMessageBrokerConfigurer { ... @Override public void registerStompEndpoints(final StompEndpointRegistry registry) { registry.addEndpoint("/myEndpoint").withSockJS(); } ``` - I want to send to the client an automatic reply from the backend (on the connection event) so that I can already provide him with some dataset (e.g. read sth from the db) without the need for him (the client) to send a GET request (or any other). So to sum up, I just want to send him a message on the topic with the SimMessagingTemplate object just after he connected. Usually I do it the following way, e.g. in a REST controller, when the template is already autowired: ``` @Autowired private SimpMessagingTemplate template; ... template.convertAndSend(TOPIC, new Message("it works!")); ``` How to achieve this on connect event? UPDATE I have managed to make it work. However, I am still a bit confused with the configuration. I will show here 2 configurations how the initial message can be sent: 1) First solution JS part ``` stompClient.subscribe('/app/pending', function(message){ showMessage(JSON.parse(message.body).content); }); stompClient.subscribe('/topic/incoming', function(message){ showMessage(JSON.parse(message.body).content); }); ``` Java part ``` @Controller public class WebSocketBusController { @SubscribeMapping("/pending") ``` Configuration ``` @Override public void configureMessageBroker(final MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); config.setApplicationDestinationPrefixes("/app"); } ``` ... and other calls ``` template.convertAndSend("/topic/incoming", outgoingMessage); ``` 2) Second solution JS part ``` stompClient.subscribe('/topic/incoming', function(message){ showMessage(JSON.parse(message.body).content); }) ``` Java part ``` @Controller public class WebSocketBusController { @SubscribeMapping("/topic/incoming") ``` Configuration ``` @Override public void configureMessageBroker(final MessageBrokerRegistry config) { config.enableSimpleBroker("/topic"); // NO APPLICATION PREFIX HERE } ``` ... and other calls ``` template.convertAndSend("/topic/incoming", outgoingMessage); ``` SUMMARY: The first case uses two subscriptions - this I wanted to avoid and thought this can be managed with one only. The second one however has no prefix for application. But at least I can have a single subscription to listen on the provided topic as well as send initial message.