使用 RabbitMQ 的自定义目的地

Custom destination with RabbitMQ

我正在尝试在我的项目中使用 RabbitMQ 作为代理,并且我想在客户端打开套接字时分配目标队列。 像这样:http://i.imgur.com/ldB2M0m.png

我设法用 SimpleBroker 做到了,但是当我尝试用 StompBrokerRelay 做到这一点时,我无法在 RabbitMQ 上分配队列并且我停止在客户端接收消息(http://i.imgur.com/gNaRHCQ.png).

我就是这样做的:

控制器:

@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
@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();
    }
}

客户:

        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));
            });
        });
    }

我知道我错过了什么。也许一些代理配置?

提前致谢!

我终于明白我漏了什么了!

Websocket 配置:

我只是在分配 topic 队列。在这种情况下,我还需要 queue 队列,一旦我想将它分配给特定的 user/channel。

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

客户:

我指的不是我想使用的队列类型。

stompClient.subscribe('/user/queue/feed', function(content) {

但这还不够。它缺少正确的安全配置。

像这样,

安全配置:

@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");
}

我添加了一个登录页面。这是没有必要的。您只需要确保密码参数用于认证即可。

现在 Rabbit 知道 user/channel,它可以将队列发送到特定的目的地。