0

私はspring websocket over stomp(スプリングブート1.5.1で動く)に基づいたWebアプリケーションを持っています。そして、私は完全機能ブローカーとしてストンププラグインを備えたRabbitmq(3.6.6)を使用しています。spring-websocketとrabbitmq-stompを使用しているときに、メッセージがすべてのアクティブなユーザに送信されない

the doc of stompによると、/ topic /からの送信先のメッセージは、すべてのアクティブなサブスクライバに配信されます。すべてのアクティブな加入者にコピー各メッセージの を配信単純なトピック送信先について

トピック送信先

、フォーム /トピックの目的地/使用することができます。トピックの宛先は、すべてのルーティング AMQPトピック交換のパターンをサポートしています。

有効なサブスクライバがないトピック宛先に送信されたメッセージは、単に廃棄されます。

しかし、動作はNOT私のアプリで上記の宣言と一致しています!

2つのブラウザで同じページを開きました。したがって、websocketサーバに接続するクライアントは2つあります。両方とも/topic/で始まる同じ宛先に登録しました。

メッセージを宛先/topic/<route key>に送信した後、1つのクライアントだけがメッセージを受信します。 2つのクライアントは、同じ宛先からのメッセージを受信するためにローテーションします。私の春のサーバー側アプリで

、私は以下のような宛先にメッセージを送信し、私のクライアント側で

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

です私の春アプリ、

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

でのWebSocketの構成は私の設定のいずれかが間違っはありますRabbitMQとStompプラグインの期間は? RabbitMQではなくを使用するとうまくいきます。

答えて

0

rabbimq-users groupでの議論によって解決されました。

私は同じIDで、耐久性のあるサブスクリプションを使用していましたが、消費者は競争力のある消費者になりました。

耐久性のあるキューを使用している場合や、自動削除キューを使用している場合に、別のクライアントIDを指定すると問題が解決しました。

関連する問題