メッセージの流れ

STOMP エンドポイントが公開されると、Spring アプリケーションは接続されたクライアントの STOMP ブローカーになります。このセクションでは、サーバー側のメッセージの流れについて説明します。

spring-messaging モジュールには、Spring Integration に由来し、後に抽出されて Spring Framework に組み込まれたメッセージングアプリケーションの基本的なサポートが含まれており、多くの Spring プロジェクトおよびアプリケーションシナリオで幅広く使用できます。以下のリストは、利用可能なメッセージング抽象化のいくつかを簡単に説明しています。

Java 構成(つまり @EnableWebSocketMessageBroker)と XML 名前空間構成(つまり <websocket:message-broker>)の両方が、前述のコンポーネントを使用してメッセージワークフローを組み立てます。次の図は、単純な組み込みメッセージブローカが有効な場合に使用されるコンポーネントを示しています。

message flow simple broker

上記の図は、3 つのメッセージチャネルを示しています。

  • clientInboundChannel: WebSocket クライアントから受信したメッセージを渡すため。

  • clientOutboundChannel: サーバーメッセージを WebSocket クライアントに送信します。

  • brokerChannel: サーバー側のアプリケーションコード内からメッセージブローカーにメッセージを送信するため。

次の図は、外部ブローカー(RabbitMQ など)がサブスクリプションの管理とメッセージのブロードキャスト用に構成されている場合に使用されるコンポーネントを示しています。

message flow broker relay

上記の 2 つの図の主な違いは、「ブローカーリレー」を使用して、TCP を介して外部 STOMP ブローカーにメッセージを渡し、ブローカーからサブスクライブされたクライアントにメッセージを渡すことです。

WebSocket 接続からメッセージを受信すると、メッセージは STOMP フレームにデコードされ、Spring Message 表現に変換され、さらなる処理のために clientInboundChannel に送信されます。例: 宛先ヘッダーが /app で始まる STOMP メッセージは、アノテーション付きコントローラーの @MessageMapping メソッドにルーティングできますが、/topic および /queue メッセージはメッセージブローカーに直接ルーティングできます。

クライアントからの STOMP メッセージを処理するアノテーション付き @Controller は、brokerChannel を介してメッセージブローカーにメッセージを送信でき、ブローカーは clientOutboundChannel を介して一致するサブスクライバーにメッセージをブロードキャストします。同じコントローラーが HTTP リクエストにレスポンスして同じことを行うことができるため、クライアントは HTTP POST を実行でき、@PostMapping メソッドはメッセージブローカーにメッセージを送信して、サブスクライブされたクライアントにブロードキャストできます。

簡単な例でフローをトレースできます。サーバーをセットアップする次の例を検討してください。

  • Java

  • Kotlin

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/portfolio");
	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		registry.setApplicationDestinationPrefixes("/app");
		registry.enableSimpleBroker("/topic");
	}
}
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfiguration : WebSocketMessageBrokerConfigurer {
	override fun registerStompEndpoints(registry: StompEndpointRegistry) {
		registry.addEndpoint("/portfolio")
	}

	override fun configureMessageBroker(registry: MessageBrokerRegistry) {
		registry.setApplicationDestinationPrefixes("/app")
		registry.enableSimpleBroker("/topic")
	}
}
  • Java

  • Kotlin

@Controller
public class GreetingController {

	@MessageMapping("/greeting")
	public String handle(String greeting) {
		return "[" + getTimestamp() + ": " + greeting;
	}

	private String getTimestamp() {
		return new SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date());
	}

}
@Controller
class GreetingController {
	
	@MessageMapping("/greeting")
	fun handle(greeting: String): String {
		return "[${getTimestamp()}: $greeting"
	}

	private fun getTimestamp(): String {
		return SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(Date())
	}
}

上記の例は、次のフローをサポートしています。

  1. クライアントは localhost:8080/portfolio に接続し、WebSocket 接続が確立されると、STOMP フレームが流れ始めます。

  2. クライアントは、宛先ヘッダー /topic/greeting で SUBSCRIBE フレームを送信します。メッセージを受信してデコードすると、メッセージは clientInboundChannel に送信され、クライアントサブスクリプションを保存するメッセージブローカーにルーティングされます。

  3. クライアントは SEND フレームを /app/greeting に送信します。/app プレフィックスは、アノテーション付きコントローラーにルーティングできます。/app プレフィックスが削除された後、宛先の残りの /greeting 部分は、GreetingController の @MessageMapping メソッドにマップされます。

  4. GreetingController から返された値は、戻り値に基づいたペイロードと /topic/greeting のデフォルトの宛先ヘッダー(/app が /topic に置き換えられた入力宛先から派生)を持つ Spring Message に変換されます。結果のメッセージは brokerChannel に送信され、メッセージブローカーによって処理されます。

  5. メッセージブローカーは一致するすべてのサブスクライバーを見つけ、clientOutboundChannel を介して各ユーザーに MESSAGE フレームを送信します。そこから、メッセージは STOMP フレームとしてエンコードされ、WebSocket 接続で送信されます。

次のセクションでは、サポートされている引数の種類や戻り値など、アノテーション付きメソッドの詳細を説明します。