I'm trying to set up a STOMP relay using RabbitMQ, Springboot, and ReactJS. I just want to be able to send a specificnotification to a specific userId.
At this stage I'm not trying to secure anything, I'm just trying to get a concept working.
Using a WebSocketChatConfig
of:
@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketChatConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry .addEndpoint("/websocket") .setAllowedOriginPatterns("*") .withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableStompBrokerRelay("/queue/user.notification") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest") .setAutoStartup(true); }}
And a RabbitConfig
of:
@Configurationpublic class RabbitConfig { private static final String TOPIC_EXCHANGE_NAME = "sockets-exchange"; private static final String ROUTING_KEY_NAME = "user.notification.#"; private static final String QUEUE_NAME = "notifications"; @Bean public Queue queue() { return new Queue(QUEUE_NAME, true); } @Bean public TopicExchange exchange() { return new TopicExchange(TOPIC_EXCHANGE_NAME); } @Bean public Binding binding(final Queue queue, final TopicExchange exchange) { return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY_NAME); } @Bean public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) { final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); rabbitTemplate.setMessageConverter(messageConverter()); return rabbitTemplate; } @Bean public Jackson2JsonMessageConverter messageConverter() { return new Jackson2JsonMessageConverter(); }}
I can send messages which are going to Rabbit, via a simple test scheduler
@Slf4j@Component@EnableScheduling@RequiredArgsConstructorpublic class TestTask { private static final String TOPIC_EXCHANGE_NAME = "sockets-exchange"; private static final String ROUTING_KEY_NAME = "user.notification"; private final RabbitTemplate rabbitTemplate; @Scheduled(fixedRate = 15, timeUnit = TimeUnit.SECONDS) public void process() { rabbitTemplate.convertAndSend( TOPIC_EXCHANGE_NAME, "%s.1".formatted(ROUTING_KEY_NAME), "This is for user 1"); rabbitTemplate.convertAndSend( TOPIC_EXCHANGE_NAME, "%s.2".formatted(ROUTING_KEY_NAME), "This is for user 2"); }}
But while I can connect to the queue via React, I'm not getting any response back when a message is pushed into thequeue.
function SubscribingComponent() { const [lastMessage, setLastMessage] = useState("No message received yet"); useSubscription("/queue/user.notification.1", (message) => { setLastMessage(message.body) }); return (<div>Last Message: {lastMessage}</div> );}
When I look in the Rabbit Management UI I can see three queues are created:
notifications
user.notification.1
user.notification.2
But all the messages are being sent into the notifications
queue, despite the code I have in TestTask
the which has me a little confused.
Do I just need to correct something in my configuration or have I missed a bigger problem?