0

我有一個基於spring websocket over stomp(由spring boot 1.5.1提供支持)的web應用程序。我使用Rabbitmq(3.6.6)和stomp插件作爲全功能代理。當使用spring-websocket和rabbitmq-stomp時不會發送消息給所有活動用戶

the doc of stomp,從/主題目標的消息/將被傳遞到所有活躍用戶。

主題目的地

對於簡單的主題目的地其中遞送每個消息的副本 到所有活動用戶,形式 /主題的目的地/都可以使用。主題目標支持AMQP主題交換的所有路由 模式。

郵件發送到一個沒有活躍用戶 被直接丟棄的主題目的地。

但行爲是不是符合上述聲明在我的應用程序!

我在兩個瀏覽器中打開了相同的頁面。因此有兩個客戶端連接到websocket服務器。他們都訂購了從/topic/開始的相同目的地。

我發送消息到目的地/topic/<route key>,但只有一個客戶端後,將收到消息。兩個客戶端將旋轉以接收來自相同目的地的消息。

在我的春天的服務器端應用程序,我將消息發送到目的地像下面,

@Secured(User.ROLE_USER) 
@MessageMapping("/comment/{liveid}") 
@SendTo("/topic/comment-{liveid}") 
public CommentMessage userComment(@DestinationVariable("liveid") String liveid, 
            @AuthenticationPrincipal UserDetails activeUser, UserComment userComment) { 
    logger.debug("Receiving comment message '{}' of live '{}' from user '{}'.", 
      userComment,liveid, activeUser.getUsername()); 
    final User user = userService.findByUsername(activeUser.getUsername()).get(); 
    return CommentMessage.builder().content(userComment.getContent()).sender(user.getNickname()) 
      .senderAvatar(user.getAvatar()).build(); 
} 

在我的客戶端,它贊同像下面的持久主題,

$stomp.subscribe('/topic/comment-' + $scope.lives[i].id, function(payload, headers, res) { 
           // do something 
          }, { 
           'durable': true, 
           'auto-delete': false 
          }); 

下面是在我的彈簧應用程序的websocket的配置,

@Configuration 
@EnableWebSocketMessageBroker 

public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> { 

@Value("${stompBroker.host:localhost}") 
String brokerHost; 
@Value("${stompBroker.port:61613}") 
int brokerPort; 
@Value("${stompBroker.login:guest}") 
String brokerLogin; 
@Value("${stompBroker.passcode:guest}") 
String brokerPasscode; 
@Value("${stompBroker.vhost:myvhost}") 
String brokerVHost; 

@Override 
protected void configureStompEndpoints(StompEndpointRegistry registry) { 
    registry.addEndpoint("/live/ws").withSockJS(); 
} 

@Override 
public void configureMessageBroker(MessageBrokerRegistry registry) { 
    registry.enableStompBrokerRelay("/topic/").setRelayHost(brokerHost).setRelayPort(
      brokerPort).setSystemLogin(brokerLogin).setSystemPasscode(brokerPasscode).setVirtualHost(brokerVHost); 

    /** 
    * Both of two subscribers can receive the message if using simple broker 
    registry.enableSimpleBroker("/topic/"); 
    */ 
    registry.setApplicationDestinationPrefixes("/app"); 
} 

@Configuration 
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { 
    @Override 
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { 
     messages.simpDestMatchers("/app/*").hasRole("USER"); 
    } 

    @Override 
    protected boolean sameOriginDisabled() { 
     return true; 
    } 
} 
} 

是否有任何錯誤的我的配置RabbitMQ和Stomp插件的使用?當使用SimpleMessageBroker而不是RabbitMQ時,它運行良好。

回答

0

這是通過rabbimq-users group的討論解決的。

我使用的是持久訂閱,使用相同的ID,消費者成爲競爭性消費者。

或者使用耐用隊列或使用自動刪除隊列時指定不同的客戶端ID解決了這個問題。