4

I am creating a spring websocket application using RabbitMQ as a broker. Is there a way to filter what web socket messages a user will see on a channel?

Multiple people will be subscribed to the channel.

redwhite
  • 405
  • 1
  • 4
  • 10
  • This question is quite wide. Are you looking to have your Spring Web App connected to a RabbitMQ topic and then depending on the message send it to different clients connected to the server via Websockets? – tobad357 Jul 08 '15 at 16:04
  • that is exactly what i am trying to do – redwhite Jul 08 '15 at 16:06
  • What do the messages look like that come across the wire? Do they have anything you can filter on like user id or similar? – tobad357 Jul 08 '15 at 16:10
  • Yes, they will have an indicator that the filtering can be done on. I am just having trouble finding some sort of presend interceptor in spring websockets. – redwhite Jul 08 '15 at 16:13

1 Answers1

2

To be able to send messages to specific users connected via Web Sockets in Spring you can use the @SendToUser annotation in combination with the SimpMessagingTemplate

The reference can be found here http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-user-destination

But in short (taken from reference) Start by setting up your topic

@Controller
public class PortfolioController {

    @MessageMapping("/trade")
    @SendToUser("/queue/position-updates")
    public TradeResult executeTrade(Trade trade, Principal principal) {
        // ...
        return tradeResult;
    }
}

Implement your own UserDestinationResolver or use the default one http://docs.spring.io/autorepo/docs/spring/4.1.3.RELEASE/javadoc-api/org/springframework/messaging/simp/user/DefaultUserDestinationResolver.html

This will resolve your path from /queue/position-updates to a unique path like /queue/position-updates-username1234 My suggestion would to use a UUID or similar to make it hard to guess

Then when you want to send messages where trade.getUsername() would be substituted for the unique id that you have choose for the channel name

public void afterTradeExecuted(Trade trade) {
        this.messagingTemplate.convertAndSendToUser(
                trade.getUserName(), "/queue/position-updates", trade.getResult());
    }

Finally when subscribing you would need to make sure the client subscribes to the right topic. This can be done by sending a queue suffix to the user through a header or Json message.

client.connect('guest', 'guest', function(frame) {

  var suffix = frame.headers['queue-suffix'];

  client.subscribe("/queue/error" + suffix, function(msg) {
    // handle error
  });

  client.subscribe("/queue/position-updates" + suffix, function(msg) {
    // handle position update
  });

});
tobad357
  • 288
  • 1
  • 6