I'm trying to use RabbitMQ as a broker on my project and I want to assign the destination queue when I open the socket on the client side. Something like this: https://i.sstatic.net/ViTF5.png
I managed to do it with SimpleBroker
, however when I try to do it with StompBrokerRelay
I can't assing the queue on RabbitMQ and I stop receiving messages on the client (https://i.sstatic.net/BawYT.png).
This is how I'm doing it:
Controller:
@RestController
public class FeedController {
@Autowired
private SimpMessageSendingOperations template;
@RequestMapping(value = "/feed", method = RequestMethod.POST, consumes = "application/json")
public Reference getLeankrReference(@RequestBody Reference ref)
{
this.template.convertAndSendToUser(ref.getChannelId(), "/topic/feed", ref);
return ref;
}
}
Websocket configuration:
@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config)
{
config.enableStompBrokerRelay("/topic/")
.setAutoStartup(true);
//config.enableSimpleBroker("/user/");
config.setApplicationDestinationPrefixes("/app");
}
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/vision").withSockJS();
}
}
Client:
function connect() {
var socket = new SockJS('/ws/vision');
var channel = document.getElementById('name').value;
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/user/' + channel + '/feed', function(message) {
showContent(JSON.parse(message.body));
});
});
}
I know that I'm missing something. Maybe some broker config?
Thank you in advance!
Finally, I figured out what I was missing!
Websocket configuration:
I was only assigning the topic queue. In this case, I need also the queue queue, once I want to assign it to a specific user/channel.
config.enableStompBrokerRelay("/queue/", "/topic/");
Client:
I wasn't referring the type of queue that I wanted to use.
stompClient.subscribe('/user/queue/feed', function(content) {
But this was not enough. It was missing the correct security configuration.
Something like this,
Security configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().addHeaderWriter(
new XFrameOptionsHeaderWriter(
XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)).and()
.formLogin()
.defaultSuccessUrl("/index.html")
.loginPage("/login.html")
.failureUrl("/login.html?error")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login.html?logout")
.logoutUrl("/logout.html")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/**").permitAll()
.anyRequest().authenticated()
.and();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("channel1").password("password").roles("USER");
}
With that I added a login page. Which is not necessary. You just need to ensure that the password parameter is used for authentication.
Now that Rabbit knows the user/channel, it can send queues to specific destinations.