メッセージの流れ
STOMP エンドポイントが公開されると、Spring アプリケーションは接続されたクライアントの STOMP ブローカーになります。このセクションでは、サーバー側のメッセージの流れについて説明します。
spring-messaging
モジュールには、Spring Integration に由来し、後に抽出されて Spring Framework に組み込まれたメッセージングアプリケーションの基本的なサポートが含まれており、多くの Spring プロジェクトおよびアプリケーションシナリオで幅広く使用できます。以下のリストは、利用可能なメッセージング抽象化のいくつかを簡単に説明しています。
メッセージ (Javadoc) : ヘッダーとペイロードを含むメッセージの単純な表現。
MessageHandler (Javadoc) : メッセージを処理するための契約。
MessageChannel (Javadoc) : プロデューサーとコンシューマー間の疎結合を可能にするメッセージを送信するための契約。
SubscribableChannel (Javadoc) :
MessageHandler
サブスクライバーを持つMessageChannel
。ExecutorSubscribableChannel (Javadoc) :
Executor
を使用してメッセージを配信するSubscribableChannel
。
Java 構成(つまり @EnableWebSocketMessageBroker
)と XML 名前空間構成(つまり <websocket:message-broker>
)の両方が、前述のコンポーネントを使用してメッセージワークフローを組み立てます。次の図は、単純な組み込みメッセージブローカが有効な場合に使用されるコンポーネントを示しています。
上記の図は、3 つのメッセージチャネルを示しています。
clientInboundChannel
: WebSocket クライアントから受信したメッセージを渡すため。clientOutboundChannel
: サーバーメッセージを WebSocket クライアントに送信します。brokerChannel
: サーバー側のアプリケーションコード内からメッセージブローカーにメッセージを送信するため。
次の図は、外部ブローカー(RabbitMQ など)がサブスクリプションの管理とメッセージのブロードキャスト用に構成されている場合に使用されるコンポーネントを示しています。
上記の 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())
}
}
上記の例は、次のフローをサポートしています。
クライアントは
localhost:8080/portfolio
に接続し、WebSocket 接続が確立されると、STOMP フレームが流れ始めます。クライアントは、宛先ヘッダー
/topic/greeting
で SUBSCRIBE フレームを送信します。メッセージを受信してデコードすると、メッセージはclientInboundChannel
に送信され、クライアントサブスクリプションを保存するメッセージブローカーにルーティングされます。クライアントは SEND フレームを
/app/greeting
に送信します。/app
プレフィックスは、アノテーション付きコントローラーにルーティングできます。/app
プレフィックスが削除された後、宛先の残りの/greeting
部分は、GreetingController
の@MessageMapping
メソッドにマップされます。GreetingController
から返された値は、戻り値に基づいたペイロードと/topic/greeting
のデフォルトの宛先ヘッダー(/app
が/topic
に置き換えられた入力宛先から派生)を持つ SpringMessage
に変換されます。結果のメッセージはbrokerChannel
に送信され、メッセージブローカーによって処理されます。メッセージブローカーは一致するすべてのサブスクライバーを見つけ、
clientOutboundChannel
を介して各ユーザーに MESSAGE フレームを送信します。そこから、メッセージは STOMP フレームとしてエンコードされ、WebSocket 接続で送信されます。
次のセクションでは、サポートされている引数の種類や戻り値など、アノテーション付きメソッドの詳細を説明します。