Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring as Broker Relay by using an external Message Broker

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?
like image 638
vdenotaris Avatar asked Sep 05 '14 08:09

vdenotaris


People also ask

What is a STOMP broker relay?

STOMP is a simple text-oriented messaging protocol that was originally created for scripting languages such as Ruby, Python, and Perl to connect to enterprise message brokers. It is designed to address a subset of commonly used messaging patterns.

What is spring message broker?

A message broker provides features like persistent storage of messages, message filtering, and message transformation. In a case of messaging between applications written in Java, the JMS (Java Message Service) API is commonly used.

What is WebSocket message broker?

The MessageBroker WebSocket Subprotocol (MBWS) is a WebSocket Subprotocol used by messaging clients to send messages to, and receive messages from an internet message broker (herein called a message broker).

What is message broker used for?

A message broker (also known as an integration broker or interface engine) is an intermediary computer program module that translates a message from the formal messaging protocol of the sender to the formal messaging protocol of the receiver.


1 Answers

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.

like image 69
Sébastien Deleuze Avatar answered Sep 25 '22 04:09

Sébastien Deleuze