How do I send a message in an Spring ApplicationListener (SessionConnectedEvent)

3.1k views Asked by At

I'm using Stomp over SockJS with Spring messaging. I'm trying to send a message to all logged in users when a new user is connected. So first off here's my listener:

@Component
public class SessionConnectedListener implements ApplicationListener<SessionConnectedEvent> {

    private static final Logger log = LoggerFactory.getLogger(SessionConnectedListener.class);

    @Autowired
    private SimpMessagingTemplate template;

    @Override
    public void onApplicationEvent(SessionConnectedEvent event) {
        log.info(event.toString());

        // Not sure if it's sending...?
        template.convertAndSend("/topic/login", "New user logged in");
    }

}

My WebSocket configurations

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("chat").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");
        config.setApplicationDestinationPrefixes("/app");
    }

}

My JS config

var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);

stompClient.connect({}}, function(frame) {

    // ... other working subscriptions

    stompClient.subscribe("/topic/login", function(message) {
        console.log(message.body);
    });

});

My problem here is that my template.convertAndSend() doesn't work in the ApplicationListener. However, if I put it in a Controller method annotated with @MessageMapping, it will work and I will have a console log client side.

So my question is : Can template.convertAndSend() work in an ApplicationListener? If so, how? or am I missing something?

Thanks for the help!

PS : my log.info(event.toString()); works in the ApplicationListener so I know I'm getting into the onApplicationEvent() method.

2

There are 2 answers

0
Philippe On BEST ANSWER

Ok! So weird as it may be, I had my Listener in the following package:

package my.company.listener;

But because of a configuration I have in my App context, the convertAndSend() method wasn't working.

@ComponentScan(basePackages = { "my.company" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { "my.company.web.*" }))

However when I moved my Listener (Annotated with @Component) to the web sub-package, it worked!

package my.company.web.listener;

1
Sergi Almar On

Sending messages with the template within an ApplicationListener should work. Please check this Spring WebSocket Chat sample for an example.