Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring web socket messaging - subscribe and send initial message

With the Stomp broker relay for web socket messaging, I can subscribe to a destination /topic/mydest. This creates a broker subscription and receives all messages that something in the system triggers for this broker destination, which happens when some event in the system occurs.

I can subscribe to a destination /app/mydest, and a controller method with @SubscribeMapping("mydest") will be called, and the return value is sent back only on this socket as a message. As far as I can tell, this is the only message that will ever be sent for this subscription.

Is there a way to combine this in a single subscription, i.e. create a broker subscription for a certain /topic destination, and trigger some code that directly sends a message back to the subscriber?

The use case: when an error occurs in the system, a message with a current error count is sent to /topic/mydest. When a new client subscribes, I want to send him only the last known error count. Others are not interested at this moment, as the count has not changed.

My current solution is to subscribe to both /app/mydest and /topic/mydest and use the same message handler on the client. But it really is one logical subscription, and it is a bit error prone as a client needs to remember to subscribe to both.

My questions in this context: will there ever be a further message for the /app/ subscription? Is there anything to call to trigger one? How else can I send initial information to a subscriber for a topic, without sending redundant messages to the existing subscribers?

As requested, here's my Websocket configuration class.

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfiguration extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableStompBrokerRelay("/queue/", "/topic/", "/exchange/");
        registry.setApplicationDestinationPrefixes("/app");
    }
}
like image 661
rainerfrey Avatar asked Nov 19 '22 05:11

rainerfrey


1 Answers

You can use ApplicationListener and SessionSubscribeEvent. Example:

@Component
public class SubscribeListener implements ApplicationListener<SessionSubscribeEvent> {

    private final SimpMessagingTemplate messagingTemplate;

    @Autowired
    public SubscribeListener(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @Override
    public void onApplicationEvent(SessionSubscribeEvent event) {
        messagingTemplate.convertAndSendToUser(event.getUser().getName(), "/topic/mydest", "Last known error count");
    }
}
like image 140
Tolledo Avatar answered Dec 21 '22 14:12

Tolledo