anchor.diff:  [[websocket-stomp-message-flow]]
   === Flow of Messages
   
  -When a STOMP endpoint is configured, the Spring application acts as the STOMP broker
  -to connected clients. This section provides a big picture overview of how messages flow
  -within the application.
  -
  -The `spring-messaging` module provides the foundation for asynchronous message processing.
  -It contains a number of abstractions that originated in the
  -https://spring.io/spring-integration[Spring Integration] project and are intended
  -for use as building blocks in messaging applications:
  +Once a STOMP endpoint is exposed, the Spring application becomes a STOMP broker for
  +connected clients. This section describes the flow of messages on the server side.
  +
  +The `spring-messaging` module contains foundational support for messaging applications
  +that originated in https://spring.io/spring-integration[Spring Integration] and was
  +later extracted and incorporated into the Spring Framework for broader use across many
  +https://spring.io/projects[Spring projects] and application scenarios.
  +Below is a list of a few of the available messaging abstractions:
   
   * {api-spring-framework}/messaging/Message.html[Message] --
  -a message with headers and a payload.
  +simple representation for a message including headers and payload.
   * {api-spring-framework}/messaging/MessageHandler.html[MessageHandler] --
  -a contract for handling a message.
  +contract for handling a message.
   * {api-spring-framework}/messaging/MessageChannel.html[MessageChannel] --
  -a contract for sending a message enabling loose coupling between senders and receivers.
  +contract for sending a message that enables loose coupling between producers and consumers.
   * {api-spring-framework}/messaging/SubscribableChannel.html[SubscribableChannel] --
  -extends `MessageChannel` and sends messages to registered `MessageHandler` subscribers.
  +`MessageChannel` with `MessageHandler` subscribers.
   * {api-spring-framework}/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel] --
  -a concrete implementation of `SubscribableChannel` that can deliver messages
  -asynchronously via a thread pool.
  -
  -The `@EnableWebSocketMessageBroker` Java config and the `<websocket:message-broker>` XML config
  -both assemble a concrete message flow. Below is a diagram of the part of the setup when using
  -the simple, in-memory broker:
  +`SubscribableChannel` that uses an `Executor` for delivering messages.
  +
  +Both the Java config (i.e. `@EnableWebSocketMessageBroker`) and the XML namespace config
  +(i.e. `<websocket:message-broker>`) use the above components to assemble a message
  +workflow. The diagram below shows the components used when the simple, built-in message
  +broker is enabled:
   
   image::images/message-flow-simple-broker.png[]
   
  -The above setup that includes 3 message channels:
  -
  -* `"clientInboundChannel"` for messages from WebSocket clients.
  -* `"clientOutboundChannel"` for messages to WebSocket clients.
  -* `"brokerChannel"` for messages to the broker from within the application.
  -
  -The same three channels are also used with a dedicated broker except here a
  -"broker relay" takes the place of the simple broker:
  +There are 3 message channels in the above diagram:
  +
  +* `"clientInboundChannel"` -- for passing messages received from WebSocket clients.
  +* `"clientOutboundChannel"` -- for sending server messages to WebSocket clients.
  +* `"brokerChannel"` -- for sending messages to the message broker from within
  +server-side, application code.
  +
  +The next diagram shows the components used when an external broker (e.g. RabbitMQ)
  +is configured for managing subscriptions and broadcasting messages:
   
   image::images/message-flow-broker-relay.png[]
   
  -Messages on the `"clientInboundChannel"` can flow to annotated
  -methods for application handling (e.g. a stock trade execution request) or can
  -be forwarded to the broker (e.g. client subscribing for stock quotes).
  -The STOMP destination is used for simple prefix-based routing. For example
  -the "/app" prefix could route messages to annotated methods while the "/topic"
  -and "/queue" prefixes could route messages to the broker.
  -
  -When a message-handling annotated method has a return type, its return
  -value is sent as the payload of a Spring `Message` to the `"brokerChannel"`.
  -The broker in turn broadcasts the message to clients. Sending a message
  -to a destination can also be done from anywhere in the application with
  -the help of a messaging template. For example, an HTTP POST handling method
  -can broadcast a message to connected clients, or a service component may
  -periodically broadcast stock quotes.
  -
  -Below is a simple example to illustrate the flow of messages:
  +The main difference in the above diagram is the use of the "broker relay" for passing
  +messages up to the external STOMP broker over TCP, and for passing messages down from the
  +broker to subscribed clients.
  +
  +When messages are received from a WebSocket connectin, they're decoded to STOMP frames,
  +then turned into a Spring `Message` representation, and sent to the
  +`"clientInboundChannel"` for further processing. For example STOMP messages whose
  +destination header starts with `"/app"` may be routed to `@MessageMapping` methods in
  +annotated controllers, while `"/topic"` and `"/queue"` messages may be routed directly
  +to the message broker.
  +
  +An annotated `@Controller` handling a STOMP message from a client may send a message to
  +the message broker through the `"brokerChannel"`, and the broker will broadcast the
  +message to matching subscribers through the `"clientOutboundChannel"`. The same
  +controller can also do the same in response to HTTP requests, so a client may perform an
  +HTTP POST and then an `@PostMapping` method can send a message to the message broker
  +to broadcast to subscribed clients.
  +
  +Let's trace the flow through a simple example. Given the following server setup:
   
   [source,java,indent=0]
   [subs="verbatim,quotes"]
  
positive.code: 
  		@Override
  		public void registerStompEndpoints(StompEndpointRegistry registry) {
  			registry.addEndpoint("/portfolio").withSockJS();
  		}
  
  		@Override
  		public void configureMessageBroker(MessageBrokerRegistry config) {
  			config.setApplicationDestinationPrefixes("/app");
  			config.enableSimpleBroker("/topic", "/queue");
  		}
  	}
  ----
  
  and in XML:
  
  [source,xml,indent=0]
  [subs="verbatim,quotes,attributes"]
  
negative.code: 
  ----
  
  . Client connects to `"http://localhost:8080/portfolio"` and once a WebSocket connection
  is established, STOMP frames begin to flow on it.
  . Client sends SUBSCRIBE frame with destination header `"/topic/greeting"`. Once received
  and decoded, the message is sent to the `"clientInboundChannel"`, then routed to the
  message broker which stores the client subscription.
  . Client sends SEND frame to `"/app/greeting"`. The `"/app"` prefix helps to route it to
  annotated controllers. After the `"/app"` prefix is stripped, the remaining `"/greeting"`
  part of the destination is mapped to the `@MessageMapping` method in `GreetingController`.
  . The value returned from `GreetingController` is turned into a Spring `Message` with
  a payload based on the return value and a default destination header of
  `"/topic/greeting"` (derived from the input destination with `"/app"` replaced by
  `"/topic"`). The resulting message is sent to the "brokerChannel" and handled
  by the message broker.
  . The message broker finds all matching subscribers, and sends a MESSAGE frame to each
  through the `"clientOutboundChannel"` from where messages are encoded as STOMP frames
  and sent on the WebSocket connection.
  
  The next section provides more details on annotated methods including the
  kinds of arguments and return values supported.
  