From 01a78bbbac05de06759f8f74b93f8fea59f4a114 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 11 Dec 2013 11:00:03 -0800 Subject: [PATCH] Add WebSocket reference documentation Update reference documentation with a new section for Spring 4's WebSocket support. --- src/asciidoc/index.adoc | 751 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 745 insertions(+), 6 deletions(-) diff --git a/src/asciidoc/index.adoc b/src/asciidoc/index.adoc index f3b029a2f4..5d2c27e457 100644 --- a/src/asciidoc/index.adoc +++ b/src/asciidoc/index.adoc @@ -184,7 +184,7 @@ old Java objects)__. [[overview-web]] ==== Web -The __Web__ layer consists of the Web, Web-Servlet, Web-Struts, and Web-Portlet modules. +The __Web__ layer consists of the Web, Web-Servlet, WebSocket and Web-Portlet modules. Spring's __Web__ module provides basic web-oriented integration features such as multipart file-upload functionality and the initialization of the IoC container using @@ -744,6 +744,7 @@ the exact version and feature set of the container. + [[spring-core]] = Core Technologies [partintro] @@ -27543,20 +27544,25 @@ within Web services. = The Web [partintro] -- -This part of the reference documentation covers the Spring Framework's support for the -presentation tier (and specifically web-based presentation tiers). +This part of the reference documentation covers Spring Framework's support for the +presentation tier (and specifically web-based presentation tiers) including support +for WebSocket-style messaging in web applications. -The Spring Framework's own web framework, <>, is covered in the -first couple of chapters. Subsequent chapters are concerned with the Spring Framework's +Spring Framework's own web framework, <>, is covered in the +first couple of chapters. Subsequent chapters are concerned with Spring Framework's integration with other web technologies, such as <> <> and others. -Following that is coverage of Spring's MVC <>. +Following that is coverage of Spring Framework's MVC <>. + +The section then concludes with comprehensive coverage of the Spring Framework +<> (including <>). * <> * <> * <> * <> +* <> -- @@ -36090,6 +36096,739 @@ Some older portals have been known to corrupt the definition of the +[[websocket]] +== WebSocket Support +This part of the reference documentation covers Spring Framework's support for +WebSocket-style messaging in web applications including use of STOMP as an +application level WebSocket sub-protocol. + +<> establishes a frame of mind in which to think about +WebSocket covering adoption challenges, design considerations, and thoughts on +it is a good fit. + +<> reviews the Spring WebSocket API on the +server-side while <> explains the SockJS protocol and shows +how to configure and use it. + +<> introduces the STOMP messaging protocol. + + + + +[[websocket-intro]] +=== Introduction +The WebSocket protocol http://tools.ietf.org/html/rfc6455[RFC 6455] defines an important +new capability for web applications: full-duplex, two-way communication between client +and server. It is an exciting new capability on the heels of a long history of +techniques to make the web more interactive including Java applets, XMLHttpRequest, +Adobe Flash, ActiveXObject, various Comet techniques, server-sent events, and others. + +A proper introduction of the WebSocket protocol is beyond the scope of this +document. At a minimum however it's important to understand that HTTP is used only for +the initial handshake, which relies on a mechanism built into HTTP to request +a protocol upgrade (or in this case a protocol switch) to which the server can respond with +HTTP status 101 (switching protocols) if it agrees. Assuming the handshake succeeds +the TCP socket underlying the HTTP upgrade request remains open and both client and +server can use it to send messages to each other. + +Spring Framework 4 includes a new `spring-websocket` module with comprehensive +WebSocket support. It is compatible with the Java WebSocket API standard (JSR-356) +and also provides additional value-add as explained in the rest of the introduction. + + + +[[websocket-into-fallback-options]] +==== Fallback Options +An important challenge to adoption is the lack of support for WebSocket in some +browsers. Notably the first Internet Explorer version to support WebSocket is +version 10 (see http://caniuse.com/websockets for support by browser versions). +Furthermore some restrictive proxies +may be configured in ways that either preclude the attempt to do HTTP upgrade +or otherwise break connection after some time because it has remained opened +for too long. For a good overview on this topic see +http://www.infoq.com/articles/Web-Sockets-Proxy-Servers[this article]. + +Therefore to build a WebSocket application today, fallback options are required +to simulate the WebSocket API where necessary. +Spring Framework provides such transparent fallback +options based on the https://github.com/sockjs/sockjs-protocol[SockJS protocol]. +These options can be enabled through configuration and do not require +modifying the application otherwise. + + + +[[websocket-intro-architecture]] +==== Messaging Architecture +Aside from short-to-midterm adoption challenges using WebSocket +brings up important design considerations that are important to recognize +early on especially in contrast to what we know about building web applications today. + +Today REST is a widely accepted, understood, and supported +architecture for building web applications. It is an architecture that relies +on having many URLs (nouns), a handful of HTTP methods (verbs), and +other principles such as using hypermedia (links), remaining stateless, etc. + +By contrast a WebSocket application may use a single URL only for the +initial HTTP handshake. All messages thereafter share and flow on the +same TCP connection. This points to an entirely different, asynchronous, +event-driven, messaging architecture. One that is much closer +to traditional messaging applications (e.g. JMS, AMQP). + +Spring Framework 4 includes a new `spring-messaging` module with key +abstractions from the +http://projects.spring.io/spring-integration/[Spring Integration] project +such as `Message`, `MessageChannel`, `MessageHandler` and others that can serve as +a foundation for such a messaging architecture. The module also includes a +set of annotations for mapping messages to methods similar to the Spring MVC +annotation based programming model. + + + +[[websocket-intro-sub-protocol]] +==== Sub-Protocol Support +WebSocket does imply a messaging architecture but does not mandate the +use of any specific messaging protocol. It is a very thin layer over TCP +that transforms a stream of bytes into a stream of messages +(either text or binary) and not much more. It is up to applications +to interpret the meaning of a message. + +Unlike HTTP which is an application-level protocol, in the WebSocket protocol +there is simply not enough information in an incoming message for a framework +or container to know how to route it or process it. Therefore WebSocket is arguably +too low level for anything but a very trivial application. It can be done but +it will likely lead to creating a framework on top. This is comparable to how +most web applications today are written using a web framework rather than the +Servlet API alone. + +For this reason the WebSocket RFC defines the use of +http://tools.ietf.org/html/rfc6455#section-1.9[sub-protocols]. +During the handshake client and server can use the header +`Sec-WebSocket-Protocol` to agree on a sub-protocol, i.e. a higher, application-level +protocol to use. The use of a sub-protocol is not required but +even if not used, applications will still need to choose a message +format that both client and server can understand. That format can be custom, +framework-specific, or a standard messaging protocol. + +Spring Framework provides support for using +http://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP] -- a simple, messaging protocol +originally created for use in scripting languages with frames inspired +by HTTP. STOMP is widely support and well suited for use over +WebSocket and over the web. + + + +[[websocket-intro-when-to-use]] +==== When To Use WebSocket? +With all design considerations surrounding the use of WebSocket, it is +reasonable to ask when is it appropriate to use? + +The best fit for WebSocket is in web applications where client and +server need to exchange events at high frequency and at low latency. Prime +candidates include but are not limited to applications in finance, games, +collaboration, and others. Such applications are both very sensitive to time +delays and also need to exchange a wide variety of messages at high +frequency. + +For other application types however this may not be the case. +For example a news or social feed that shows breaking news as they become +available may be perfectly okay with simple polling once every few minutes. +Here latency is important but it is not as crucial if the news takes a +few minutes to appear. + +Even in cases where latency is crucial, if the volume of messages is +relatively low (e.g. monitoring network failures) the use of +http://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates[long polling] +should be considered as a relatively simple alternative that +works reliably and is comparable by efficiency (again assuming the volume of +messages is relatively low). + +It is the combination of both low latency and high frequency of messages that can make +the use of the WebSocket protocol critical. Even in such applications +the choice remains whether all client-server +communication should be done through WebSocket messages as opposed to using +HTTP and REST? The answer is going to vary by application, however it is likely +that some functionality may be exposed over both WebSocket and as a REST API in +order to provide clients with alternatives. Furthermore a REST API call may need +to broadcast a message to interested clients connected via WebSocket. + +Spring Framework allows `@Controller` classes to have both +HTTP request handling and WebSocket message handling methods. +Furthermore, a Spring MVC request handling method, or any application +method for that matter, can easily broadcast a message to all interested +WebSocket clients or to a specific user. + + + + +[[websocket-server]] +=== WebSocket Server +The Spring Framework provides a WebSocket API designed to adapt to various WebSocket engines. +For example it runs on JSR-356 runtimes such as Tomcat (7.0.47+) and Glassfish (4.0+) but +can also adapt to other WebSocket runtimes such as the Jetty (9.0+) native WebSocket support. + +[NOTE] +==== +As explained in the <> direct use of a +WebSocket API is too low level for applications -- until assumptions are made about the +format of a message there is little a framework can do to interpret messages or route +them via annotations. This is why applications should consider using a sub-protocol +and Spring's <> support. + +When using a higher level protocol, the details of the WebSocket API become less +relevant much like the details of TCP communication are not exposed to applications +when using HTTP. Nevertheless this section covers the details of using WebSocket +directly. +==== + + + +[[websocket-server-handler]] +==== Create and Configure a WebSocketHandler +Creating a WebSocket server is as simple as implementing `WebSocketHandler` or more +likely extending either `TextWebSocketHandler` or `BinaryWebSocketHandler`: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + import org.springframework.web.socket.WebSocketHandler; + import org.springframework.web.socket.WebSocketSession; + import org.springframework.web.socket.TextMessage; + + public class MyHandler extends TextWebSocketHandler { + + @Override + public void handleTextMessage(WebSocketSession session, TextMessage message) { + // ... + } + + } +---- + +There is dedicated WebSocket Java-config and XML namespace support for mapping the above +WebSocket handler at a specific URL: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + import org.springframework.web.socket.config.annotation.EnableWebSocket; + import org.springframework.web.socket.config.annotation.WebSocketConfigurer; + import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + + @Configuration + @EnableWebSocket + public class WebSocketConfig implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(myHandler(), "/myHandler"); + } + + @Bean + public WebSocketHandler myHandler() { + return new MyHandler(); + } + + } +---- + +XML configuration equivalent: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + + + + + + +---- + +The above is for use in Spring MVC applications and should be included in the +configuration of a <>. However, Spring's WebSocket +support does not depend on Spring MVC. It is relatively simple to integrate a `WebSocketHandler` +into other HTTP serving environments with the help of +https://github.com/spring-projects/spring-framework/blob/master/spring-websocket/src/main/java/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.java[WebSocketHttpRequestHandler]. + + + +[[websocket-server-handshake]] +==== Customizing the WebSocket Handshake +The easiest way to customize the initial HTTP WebSocket handshake request is through +a `HandshakeInterceptor`, which exposes before and after the handshake methods. +Such an interceptor can be used to preclude the handshake or to make any attributes +available to the `WebSocketSession`. For example there is a built-in interceptor +for passing HTTP session attributes to the WebSocket session: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + @Configuration + @EnableWebSocket + public class WebSocketConfig implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(new MyHandler(), "/myHandler") + .addInterceptors(new HttpSessionHandshakeInterceptor()); + } + + } +---- + +And the XML configuration equivalent: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + + + + + + + + + +---- + +A more advanced option is to extend the `DefaultHandshakeHandler` that performs +the steps of the WebSocket handshake including validating the client origin, +negotiating a sub-protocol, and others. An application may also need to use this +option if it needs to configure a custom `RequestUpgradeStrategy` in order to +adapt to a WebSocket server engine and version that is not yet supported +(also see <> for more on this subject). +Both the Java config and XML namespace make it possible to configure a custom +`HandshakeHandler`. + + + +[[websocket-server-decorators]] +==== WebSocketHandler Decoration +Spring provides a `WebSocketHandlerDecorator` base class that can be used to decorate +a `WebSocketHandler` with additional behavior. Logging and exception handling +implementations are provided and added by default when using the WebSocket Java config +or XML namespace. The `ExceptionWebSocketHandlerDecorator` catches all uncaught +exceptions arising from any WebSocketHandler method and closes the WebSocket +session with status `1011` that indicates a server error. + + + +[[websocket-server-deployment]] +==== Deployment Considerations +The Spring WebSocket API is easy to integrate into a Spring MVC application where +the `DispatcherServlet` serves both HTTP WebSocket handshake as well as other +HTTP requests. It is also easy to integrate into other HTTP processing scenarios +by invoking `WebSocketHttpRequestHandler`. This is convenient and easy to +understand. However special considerations apply with regards to JSR-356 runtimes. + +The Java WebSocket API (JSR-356) provides two deployment mechanisms. The first +involves a Servlet container classpath scan (Servlet 3 feature) at startup and +the other is a registration API to use at Servlet container initialization. +Neither of these mechanism make it possible to use a single "front controller" +for all HTTP processing -- including WebSocket handshake and all other HTTP +requests -- such as Spring MVC's `DispatcherServlet`. + +This is a significant limitation of JSR-356 that Spring's WebSocket support +addresses by providing a server-specific `RequestUpgradeStrategy` even when +running in a JSR-356 runtime. At present such support is available on +Tomcat 7.0.47+, Jetty 9.0+, and Glassfish 4.0+. Additional support will be +added as more WebSocket runtimes become available. + +[NOTE] +==== +A request to overcome the above limitation in the Java WebSocket API has been +created and can be followed at +https://java.net/jira/browse/WEBSOCKET_SPEC-211[WEBSOCKET_SPEC-211]. +Also note that Tomcat and Jetty already provide native API alternatives that +makes it easy to overcome the limitation. We are hopeful that more servers +will follow their example regardless of when it is addressed in the +Java WebSocket API. +==== + +A secondary consideration is that Servlet containers with JSR-356 support +are expected to perform an SCI scan that can slow down application startup +in some cases dramatically. If a significant impact is observed after an +upgrade to a Servlet container version with JSR-356 support, it should +be possible to selectively enable or disable web fragments (and SCI scanning) +through the use of an `` element in web.xml: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + + +---- + +You can then selectively enable web fragments by name, such as Spring's own +`SpringServletContainerInitializer` that provides support for the Servlet 3 +Java initialization API, if required: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + spring_web + + + +---- + + + + +[[websocket-fallback]] +=== Fallback Options +As explained in the <> WebSocket is not +supported in all browsers yet or may be precluded by restrictive network proxies. +This is why Spring provides fallback options that emulate the WebSocket API as close +as possible based on the https://github.com/sockjs/sockjs-protocol[SockJS protocol]. + + + +[[websocket-fallback-sockjs-enable]] +==== Enable SockJS +SockJS is easy to enable through a configuration: + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + @Configuration + @EnableWebSocket + public class WebSocketConfig implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(myHandler(), "/myHandler").withSockJS(); + } + + @Bean + public WebSocketHandler myHandler() { + return new MyHandler(); + } + + } +---- + +and the XML configuration equivalent: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + + + + + + + +---- + +The above is for use in Spring MVC applications and should be included in the +configuration of a <>. However, Spring's WebSocket +and SockJS support does not depend on Spring MVC. It is relatively simple to +integrate into other HTTP serving environments with the help of +https://github.com/spring-projects/spring-framework/blob/master/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.java[SockJsHttpRequestHandler]. + +On the browser side, applications can use the +https://github.com/sockjs/sockjs-client[sockjs-client] that emulates the W3C +WebSocket API and communicates with the server to select the best +transport option depending on the browser it's running in. Review the +https://github.com/sockjs/sockjs-client[sockjs-client] page and the list of +transport types supported by browser. The client also provides several +configuration options, for example to specify which transports to include. + + + +[[websocket-fallback-sockjs-explained]] +==== How SockJS Works +An in-depth description of how SockJS works is beyond the scope of this document. +This section summarizes a few key facts to aid with understanding. +The SockJS protocol itself is defined in a +https://github.com/sockjs/sockjs-protocol/blob/master/sockjs-protocol-0.3.3.py[test suite] +with comments explaining the protocol. There is also an +http://sockjs.github.io/sockjs-protocol/sockjs-protocol-0.3.3.html[HTML version of that test] +showing comments on the right and code on the left. + +The SockJS client issues HTTP requests with this URL structure: + +.SockJS URL +---- +http://host:port/{path-to-sockjs-endpoint}/{server-id}/{session-id}/{transport} +---- + +The WebSocket transport type uses a single HTTP connection to perform a +WebSocket handshake and establish an actual WebSocket session. HTTP-based +transports on the other hand must simulate the WebSocket API and at any time +may use two HTTP connections -- one for server-to-client messages, via +https://spring.io/blog/2012/05/08/spring-mvc-3-2-preview-techniques-for-real-time-updates[HTTP streaming or long polling], +and another for sending client messages to the server via HTTP POST. + +The session id is useful with HTTP transports to associate individual HTTP +requests that belong to the same SockJS session. The server id is not used in the +protocol but is added to help in clustered environments. + +SockJS adds a minimal amount of message framing. For example the server can send +an "open frame" (the letter +o+), a "heartbeat frame" (the letter +h+), or a +"close frame" (the letter +c+) while the client sends messages as a JSON-encoded +array prepended with the letter "a" (e.g. +a["message1","message2"]+). + +By default the server sends a heartbeat frame every 25 seconds to keep proxies +and loadbalancers from timing out the connection. + + + +[[websocket-fallback-sockjs-spring]] +==== Spring's SockJS Support +In the Spring Framework, server-side support for the SockJS protocol is provided through a +hierarchy of classes that implement the `SockJsService` interface while +`SockJsHttpRequestHandler` integrates the service into HTTP request processing. + +To implement HTTP streaming and long polling both of which require an HTTP connection +to remain open longer than usual, in Servlet containers Spring's SockJS support +relies on Servlet 3 async support. + +[WARNING] +==== +Servlet 3 async support does not expose a notification when a client disconnects, +e.g. a browser tab is closed, page is refreshed, etc +(see https://java.net/jira/browse/SERVLET_SPEC-44[SERVLET_SPEC-44]). However, the +Serlvet container will usually raise an IOException on the next attempt to write +to the response at which point the SockJS session will be closed. Since the +SockJsService sends a heartbeat every 25 seconds, typically a disconnected +client will be detected within that time period. +==== + + + + +[[websocket-stomp]] +=== STOMP Messaging +The WebSocket protocol defines two main types of messages -- text and binary -- +but leaves their content undefined. Instead it's expected that client and +server may agree on using a sub-protocol, i.e. a higher-level protocol that defines +the message content. Using a sub-protocol is optional but either way client +and server both need to understand how to interpret messages. + + + +[[websocket-stomp-overview]] +==== STOMP Overview +http://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP] is a simple +messaging protocol originally created to connect to enterprise message brokers from +scripting languages such as Ruby, Python and Perl. It is designed to address a +subset of commonly used patterns in messaging protocols. STOMP can be used over +any reliable 2-way streaming network protocol such as TCP and WebSocket. + +STOMP is a frame based protocol with frames modelled on HTTP. This is the +structure of a frame: + +---- +COMMAND +header1:value1 +header2:value2 + +Body^@ +---- + +For example a client can use the +SEND+ command to send a message or the ++SUBSCRIBE+ command to express interest in receiving messages. Both of these commands +require a +"destination"+ header that indicates where to send a message to or likewise +what to subscribe to. + +Here is an example of a client sending a request to buy stock shares: + +---- +SEND +destination:/queue/trade +content-type:application/json +content-length:44 + +{"action":"BUY","ticker":"MMM","shares",44}^@ +---- + +Here is an example of a client subscribing to receive stock quotes: +---- +SUBSCRIBE +id:sub-1 +destination:/topic/price.stock.* + +^@ +---- + +[NOTE] +==== +The meaning of a destination is intentionally left opaque in the STOMP spec. It can +be any string and it's entirely up to STOMP servers to define the semantics and +the syntax of destinations they support. It is very common however for destinations +to be path-like strings where "/topic/.." implies publish-subscribe (one-to-many) +and "/queue/" to implies point-to-point (one-to-one) message exchanges. +==== + +STOMP servers can use the +MESSAGE+ command to broadcast messages to all subscribers. +Here is an example of a server sending a stock quote to a subscribed client: + +---- +MESSAGE +message-id:nxahklf6-1 +subscription:sub-1 +destination:/topic/price.stock.MMM + +{"ticker":"MMM","price":129.45}^@ +---- + +[NOTE] +==== +It's important to know that a server cannot send unsolicited messages. +All messages from a server must be in response to a specific client subscription +and the +"subscription-id"+ header of the server message must match +the +"id"+ header of the client subscription. +==== + +The above overview is intended to provide the most basic understanding of the +STOMP protocol. It is recommended to review the protocol +http://stomp.github.io/stomp-specification-1.2.html[specification], which is +easy to follow and manageable in terms of size. + +The following summarizes the benefits for an application from using STOMP over WebSocket: + +* Standard message format +* Application-level protocol with support for common messaging patterns +* Client-side support, e.g. https://github.com/jmesnil/stomp-websocket[stomp.js], https://github.com/cujojs/msgs[msgs.js] +* The ability to interpret, route, and process messages on both client and server-side +* The option to plug a message broker -- RabbitMQ, ActiveMQ, many others -- to broadcast messages (explained later) + +Most importantly the use of STOMP (vs plain WebSocket) enables the Spring Framework +to provide a programming model for application-level use in the same way that +Spring MVC provides a programming model based on HTTP. + + + +[[websocket-stomp-enable]] +==== Enable STOMP over WebSocket +The Spring Framework provides support for using STOMP over WebSocket through +the +spring-messaging+ and +spring-websocket+ modules. It's easy to enable it. + +Here is an example of configuring a STOMP WebSocket endpoint with SockJS fallback +options. The endpoint is available for clients to connect to at URL path "/portfolio": + +[source,java,indent=0] +[subs="verbatim,quotes"] +---- + import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; + import org.springframework.web.socket.config.annotation.StompEndpointRegistry; + + @Configuration + @EnableWebSocketMessageBroker + public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/portfolio").withSockJS(); + } + + // ... + + } +---- + +XML configuration equivalent: + +[source,xml,indent=0] +[subs="verbatim,quotes,attributes"] +---- + + + + + + + ... + + + +---- + +On the browser side, a client might connect as follows using +https://github.com/jmesnil/stomp-websocket[stomp.js] and the +https://github.com/sockjs/sockjs-client[sockjs-client]: + +[source,javascript,indent=0] +[subs="verbatim,quotes"] +---- + var socket = new SockJS("/spring-websocket-portfolio/portfolio"); + var stompClient = Stomp.over(socket); +---- + +Or if connecting via WebSocket (without SockJS): + +[source,javascript,indent=0] +[subs="verbatim,quotes"] +---- + var socket = new WebSocket("/spring-websocket-portfolio/portfolio"); + var stompClient = Stomp.over(socket); +---- + + + +[[websocket-stomp-handle]] +==== Handling STOMP Messages +When STOMP is enabled, the Spring application is effectively becomes a STOMP +broker to connected clients. + + [[spring-integration]] = Integration [partintro]