2017-11-12 2 views
0

RabbitMQブローカーを使用してクラスタ化されたTomcat環境でSpring Websocketを使用してアプリケーションを構築しています。私は聞くエンドポイントを登録する必要があるAPIモジュールを持っています。私は、通常の例に続き、この設定を思い付いた:これは動作しますが、そのためできない他の層を残して、すべてのAPIモジュールにバンドルされているのWebSocketとリレー設定を表示されるアプリケーションの他のレイヤーからSTOMPメッセージを送信する

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer 
{ 
    @Override 
    public void configureMessageBroker(final MessageBrokerRegistry config) 
    { 
     config.enableStompBrokerRelay("/topic/") 
      .setRelayHost("localhost") 
      .setRelayPort(61613) 
      .setClientLogin("guest") 
      .setClientPasscode("guest"); 
    } 

    @Override 
    public void registerStompEndpoints(final StompEndpointRegistry registry) 
    { 
     registry.addEndpoint("/updates") 
      .setAllowedOrigins("*") 
      .withSockJS(); 
    } 
} 

が、それは私の問題を解決しませんブローカーを再利用する。私たちのアプリの他のモジュールがRabbitMQのトピックにメッセージをプッシュできるように、サービス層でストップメッセージブローカリレー設定が必要になり、開いて開いているWebソケットをすべて更新するAPIモジュールに通知します。

以下は、アプリケーションの関連するレイヤーのサンプルダイアグラムと、私が達成しようとしているものです。私はモジュール「Cron Message Sender」が他のAPIモジュールを通してメッセージトピックに加入しているすべての人にメッセージをプッシュできるようにする必要があります。

Sample Application Layers

+0

私は右模索しています他の可能性のあるアイデア2つを完全に別々のコンポーネントに分割することです。これは、各APIモジュールが、単純なブローカー(リレーなし)を使用して独自のWebSocket構成を実行することを意味しています。その後、サービス層では、AMQPを介してrabbitmqと直接話し合って、各サービスインスタンスを接続します。次に、各APIモジュールは着信AMQPメッセージをリッスンし、Stomp WS経由でそれぞれのユーザーに転送します。私はまだメッセージングを初めて学んでおり、これが実稼働環境でのパフォーマンスの点でより良いか悪いかはわかりません。 –

+0

このアプローチがうまくいくとすれば、RabbitMQからAWS SQSのような他のメッセージブローカーに移行することに決めれば、コンポーネントのデカップリングが可能になり、柔軟性を高めることができます。 –

答えて

1

ので、第2のアプローチは、実際の仕事でやりました。私はWebソケットを独立して(リレーなしで)実行するように設定してから、サービス層間の通信を可能にするためにサービスレイヤで別々のAMQPメッセージブローカ接続を作成しました。 APIモジュールでは、私は単にAMQPメッセージブローカーの声を聞いて、手動でこれらのメッセージをSimpMessagingTemplateに転送しました。これはwebsocket加入者に通知しました。これが技術的に「正しい」方法であるかどうかはわかりませんが、うまくいくように見えますが、実装にはまだ問題はありません。実際には、私は今、私のサービスが、当初WebSocketに必要だったよりも多くの種類のメッセージでお互いに話す能力を与えたので、このアプローチを好むかもしれないと私は実際考えています。ここで

は、新たな構成です:私は、メッセージブローカに耳を傾け、WebSocketの加入者にメッセージを転送する場所

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer 
{ 
    @Override 
    public void configureMessageBroker(final MessageBrokerRegistry config) 
    { 
     config.enableSimpleBroker("/topic"); 
    } 

    @Override 
    public void registerStompEndpoints(final StompEndpointRegistry registry) 
    { 
     registry.addEndpoint("/updates") 
      .setAllowedOrigins("*") 
      .withSockJS(); 
    } 
} 

そして、ここでは、次のとおりです。

@Component 
public class SendWebSocketUpdates 
{ 
    private static final Logger logger = LoggerFactory.getLogger(SendWebSocketUpdates.class); 

    private final Gson gson; 

    @Autowired 
    private SimpMessagingTemplate messagingTemplate; 

    @Autowired 
    private MessageBrokerConsumer<String> messageBrokerConsumer; 

    public SendWebSocketUpdates() 
    { 
     this.gson = new Gson(); 
    } 

    @PostConstruct 
    public void init() 
    { 
     //listen for incoming AMQP messages from the rabbitmq server and forward them to the websocket subscribers 
     messageBrokerConsumer.addListener((message, topicName) -> { 
      final String destination = "/topic/" + topicName; 
      final String messageJson = gson.toJson(message.getBody()); 

      //check to see if trace logging is enabled 
      if (logger.isTraceEnabled()) 
      { 
       logger.trace("Sending Message to \"{}\": {}", destination, messageJson); 
      } 

      //broadcast the via a STOMP message to subscribers of this topic 
      messagingTemplate.convertAndSend(destination, messageJson); 
     }); 
    } 
} 
関連する問題