8
votes

I would like to use Spring Messaging to create a real time notification system for logged users for my webapp.

I defined a AbstractWebSocketMessageBrokerConfigurer as follows:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/notifications").withSockJS()
        .setSessionCookieNeeded(true)
        .setWebSocketEnabled(true);
}

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

And, according to the documentation:

An application can send messages targeting a specific user. Spring’s STOMP support recognizes destinations prefixed with "/user/". For example, a client might subscribe to the destination "/user/queue/position-updates". This destination will be handled by the UserDestinationMessageHandler and transformed into a destination unique to the user session, e.g. "/queue/position-updates-user123". This provides the convenience of subscribing to a generically named destination while at the same time ensuring no collisions with other users subscribing to the same destination so that each user can receive unique stock position updates.

On the sending side messages can be sent to a destination such as "/user/{username}/queue/position-updates", which in turn will be translated by the UserDestinationMessageHandler into one or more destinations, one for each session associated with the user. This allows any component within the application to send messages targeting a specific user without necessarily knowing anything more than their name and the generic destination. This is also supported through an annotation as well as a messaging template.

By sending a message to /user/{username}/queue/something, it will be delivered only to the specific user identified by {username}.

Now, I'm looking for a solution that allows me to use an external Message Broker (for instance, RabbitMQ), with Spring just as Broker Relay:

registry.enableStompBrokerRelay("/topic/", "/queue/");

After configuring the External Message Broker in Spring:

  • Is it possible to send a message on Message Broker by using as channel /user/{username/}/queue/something? If yes, how?
  • By sending a message on Message Broker by using as channel /user/{username/}/queue/something, is Spring able to send that message only to {username} according to the current Principal?
1

1 Answers

3
votes

Yes it is possible, if you enable an external broker, every @MessageMapping return value will be serialized to JSON and sent to the broker, have a look to the Flow of Messages section of the reference documentation for more details. So it is basically the same that with the simple broker.

You can also inject a SimpMessagingTemplate or SimpMessageSendingOperations bean, like it is done in my OpenSnap example application. You can use this from a Controller, but also from any other class in a pure push context.

You can retrieve the principal by adding a Principal parameter to your @MessageMapping or @SubscribeMapping handler method, like it is done here, the current principal will be automatically injected.