Final documentation polish before 4.0
This commit is contained in:
parent
e637418010
commit
421292acf4
|
@ -829,9 +829,12 @@ remain compatible with Google App Engine and older application servers, it is po
|
||||||
to deploy a Spring application into a Servlet 2.5 environment; however, Servlet 3.0+
|
to deploy a Spring application into a Servlet 2.5 environment; however, Servlet 3.0+
|
||||||
is recommended when at all possible.
|
is recommended when at all possible.
|
||||||
|
|
||||||
Note: If you are a WebSphere 7 user, be sure install the JPA 2.0 feature pack. On
|
[NOTE]
|
||||||
|
====
|
||||||
|
If you are a WebSphere 7 user, be sure install the JPA 2.0 feature pack. On
|
||||||
WebLogic 10.3.4 or higher, install the JPA 2.0 patch that comes with it. This turns
|
WebLogic 10.3.4 or higher, install the JPA 2.0 patch that comes with it. This turns
|
||||||
both of those server generations into Spring 4 compatible deployment environments.
|
both of those server generations into Spring 4 compatible deployment environments.
|
||||||
|
====
|
||||||
|
|
||||||
On a more forward-looking note, Spring Framework 4.0 supports the Java EE 7 level of
|
On a more forward-looking note, Spring Framework 4.0 supports the Java EE 7 level of
|
||||||
applicable specifications now: in particular, JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation
|
applicable specifications now: in particular, JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation
|
||||||
|
@ -18412,7 +18415,7 @@ As of Spring Framework 4.0, it is now possible to use test-related annotations
|
||||||
as <<beans-meta-annotations,meta-annotations>> in order to create custom
|
as <<beans-meta-annotations,meta-annotations>> in order to create custom
|
||||||
_composed annotations_ and reduce configuration duplication across tests.
|
_composed annotations_ and reduce configuration duplication across tests.
|
||||||
|
|
||||||
Each of the following may be used as meta-annotations in conjunction with the
|
Each of the following may be used as meta-annotations in conjunction with the
|
||||||
<<testcontext-framework,TestContext framework>>.
|
<<testcontext-framework,TestContext framework>>.
|
||||||
|
|
||||||
* `@ContextConfiguration`
|
* `@ContextConfiguration`
|
||||||
|
@ -36503,7 +36506,7 @@ WebSocket-style messaging in web applications including use of STOMP as an
|
||||||
application level WebSocket sub-protocol.
|
application level WebSocket sub-protocol.
|
||||||
|
|
||||||
<<websocket-intro>> establishes a frame of mind in which to think about
|
<<websocket-intro>> establishes a frame of mind in which to think about
|
||||||
WebSocket covering adoption challenges, design considerations, and thoughts on
|
WebSocket, covering adoption challenges, design considerations, and thoughts on
|
||||||
when it is a good fit.
|
when it is a good fit.
|
||||||
|
|
||||||
<<websocket-server>> reviews the Spring WebSocket API on the
|
<<websocket-server>> reviews the Spring WebSocket API on the
|
||||||
|
@ -36532,7 +36535,8 @@ the TCP socket underlying the HTTP upgrade request remains open and both client
|
||||||
server can use it to send messages to each other.
|
server can use it to send messages to each other.
|
||||||
|
|
||||||
Spring Framework 4 includes a new `spring-websocket` module with comprehensive
|
Spring Framework 4 includes a new `spring-websocket` module with comprehensive
|
||||||
WebSocket support. It is compatible with the Java WebSocket API standard (JSR-356)
|
WebSocket support. It is compatible with the Java WebSocket API standard
|
||||||
|
(http://jcp.org/en/jsr/detail?id=356[JSR-356])
|
||||||
and also provides additional value-add as explained in the rest of the introduction.
|
and also provides additional value-add as explained in the rest of the introduction.
|
||||||
|
|
||||||
|
|
||||||
|
@ -36542,11 +36546,13 @@ and also provides additional value-add as explained in the rest of the introduct
|
||||||
An important challenge to adoption is the lack of support for WebSocket in some
|
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
|
browsers. Notably the first Internet Explorer version to support WebSocket is
|
||||||
version 10 (see http://caniuse.com/websockets for support by browser versions).
|
version 10 (see http://caniuse.com/websockets for support by browser versions).
|
||||||
Furthermore some restrictive proxies
|
Furthermore, some restrictive proxies
|
||||||
may be configured in ways that either preclude the attempt to do HTTP upgrade
|
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
|
or otherwise break connection after some time because it has remained opened
|
||||||
for too long. For a good overview on this topic see
|
for too long. A good overview on this topic from Peter Lubbers is available in
|
||||||
http://www.infoq.com/articles/Web-Sockets-Proxy-Servers[this article].
|
the InfoQ article
|
||||||
|
http://www.infoq.com/articles/Web-Sockets-Proxy-Servers["How HTML5 Web Sockets Interact With Proxy Servers"].
|
||||||
|
|
||||||
|
|
||||||
Therefore to build a WebSocket application today, fallback options are required
|
Therefore to build a WebSocket application today, fallback options are required
|
||||||
to simulate the WebSocket API where necessary.
|
to simulate the WebSocket API where necessary.
|
||||||
|
@ -36559,14 +36565,14 @@ modifying the application otherwise.
|
||||||
|
|
||||||
[[websocket-intro-architecture]]
|
[[websocket-intro-architecture]]
|
||||||
==== Messaging Architecture
|
==== Messaging Architecture
|
||||||
Aside from short-to-midterm adoption challenges using WebSocket
|
Aside from short-to-midterm adoption challenges, using WebSocket
|
||||||
brings up important design considerations that are important to recognize
|
brings up important design considerations that are important to recognize
|
||||||
early on especially in contrast to what we know about building web applications today.
|
early on, especially in contrast to what we know about building web applications today.
|
||||||
|
|
||||||
Today REST is a widely accepted, understood, and supported
|
Today REST is a widely accepted, understood, and supported
|
||||||
architecture for building web applications. It is an architecture that relies
|
architecture for building web applications. It is an architecture that relies
|
||||||
on having many URLs (nouns), a handful of HTTP methods (verbs), and
|
on having many URLs (__nouns__), a handful of HTTP methods (__verbs__), and
|
||||||
other principles such as using hypermedia (links), remaining stateless, etc.
|
other principles such as using hypermedia (__links__), remaining stateless, etc.
|
||||||
|
|
||||||
By contrast a WebSocket application may use a single URL only for the
|
By contrast a WebSocket application may use a single URL only for the
|
||||||
initial HTTP handshake. All messages thereafter share and flow on the
|
initial HTTP handshake. All messages thereafter share and flow on the
|
||||||
|
@ -36579,32 +36585,32 @@ abstractions from the
|
||||||
http://projects.spring.io/spring-integration/[Spring Integration] project
|
http://projects.spring.io/spring-integration/[Spring Integration] project
|
||||||
such as `Message`, `MessageChannel`, `MessageHandler` and others that can serve as
|
such as `Message`, `MessageChannel`, `MessageHandler` and others that can serve as
|
||||||
a foundation for such a messaging architecture. The module also includes a
|
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
|
set of annotations for mapping messages to methods, similar to the Spring MVC
|
||||||
annotation based programming model.
|
annotation based programming model.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[websocket-intro-sub-protocol]]
|
[[websocket-intro-sub-protocol]]
|
||||||
==== Sub-Protocol Support
|
==== Sub-Protocol Support
|
||||||
WebSocket does imply a messaging architecture but does not mandate the
|
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
|
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
|
that transforms a stream of bytes into a stream of messages
|
||||||
(either text or binary) and not much more. It is up to applications
|
(either text or binary) and not much more. It is up to applications
|
||||||
to interpret the meaning of a message.
|
to interpret the meaning of a message.
|
||||||
|
|
||||||
Unlike HTTP which is an application-level protocol, in the WebSocket protocol
|
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
|
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
|
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
|
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
|
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
|
most web applications today are written using a web framework rather than the
|
||||||
Servlet API alone.
|
Servlet API alone.
|
||||||
|
|
||||||
For this reason the WebSocket RFC defines the use of
|
For this reason the WebSocket RFC defines the use of
|
||||||
http://tools.ietf.org/html/rfc6455#section-1.9[sub-protocols].
|
http://tools.ietf.org/html/rfc6455#section-1.9[sub-protocols].
|
||||||
During the handshake client and server can use the header
|
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
|
`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
|
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
|
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,
|
format that both client and server can understand. That format can be custom,
|
||||||
framework-specific, or a standard messaging protocol.
|
framework-specific, or a standard messaging protocol.
|
||||||
|
@ -36619,7 +36625,7 @@ WebSocket and over the web.
|
||||||
|
|
||||||
[[websocket-intro-when-to-use]]
|
[[websocket-intro-when-to-use]]
|
||||||
==== When To Use WebSocket?
|
==== When To Use WebSocket?
|
||||||
With all design considerations surrounding the use of WebSocket, it is
|
With all the design considerations surrounding the use of WebSocket, it is
|
||||||
reasonable to ask when is it appropriate to use?
|
reasonable to ask when is it appropriate to use?
|
||||||
|
|
||||||
The best fit for WebSocket is in web applications where client and
|
The best fit for WebSocket is in web applications where client and
|
||||||
|
@ -36629,10 +36635,10 @@ collaboration, and others. Such applications are both very sensitive to time
|
||||||
delays and also need to exchange a wide variety of messages at high
|
delays and also need to exchange a wide variety of messages at high
|
||||||
frequency.
|
frequency.
|
||||||
|
|
||||||
For other application types however this may not be the case.
|
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
|
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.
|
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
|
Here latency is important, but it is acceptable if the news takes a
|
||||||
few minutes to appear.
|
few minutes to appear.
|
||||||
|
|
||||||
Even in cases where latency is crucial, if the volume of messages is
|
Even in cases where latency is crucial, if the volume of messages is
|
||||||
|
@ -36643,12 +36649,12 @@ works reliably and is comparable by efficiency (again assuming the volume of
|
||||||
messages is relatively low).
|
messages is relatively low).
|
||||||
|
|
||||||
It is the combination of both low latency and high frequency of messages that can make
|
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 use of the WebSocket protocol critical. Even in such applications,
|
||||||
the choice remains whether all client-server
|
the choice remains whether all client-server
|
||||||
communication should be done through WebSocket messages as opposed to using
|
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
|
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
|
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
|
order to provide clients with alternatives. Furthermore, a REST API call may need
|
||||||
to broadcast a message to interested clients connected via WebSocket.
|
to broadcast a message to interested clients connected via WebSocket.
|
||||||
|
|
||||||
Spring Framework allows `@Controller` classes to have both
|
Spring Framework allows `@Controller` classes to have both
|
||||||
|
@ -36663,19 +36669,19 @@ WebSocket clients or to a specific user.
|
||||||
[[websocket-server]]
|
[[websocket-server]]
|
||||||
=== WebSocket Server
|
=== WebSocket Server
|
||||||
The Spring Framework provides a WebSocket API designed to adapt to various WebSocket engines.
|
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
|
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.
|
can also adapt to other WebSocket runtimes such as the Jetty (9.0+) native WebSocket support.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
As explained in the <<websocket-intro-sub-protocol,introduction>> direct use of a
|
As explained in the <<websocket-intro-sub-protocol,introduction>>, direct use of a
|
||||||
WebSocket API is too low level for applications -- until assumptions are made about the
|
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
|
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
|
them via annotations. This is why applications should consider using a sub-protocol
|
||||||
and Spring's <<websocket-stomp,STOMP over WebSocket>> support.
|
and Spring's <<websocket-stomp,STOMP over WebSocket>> support.
|
||||||
|
|
||||||
When using a higher level protocol, the details of the WebSocket API become less
|
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
|
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
|
when using HTTP. Nevertheless this section covers the details of using WebSocket
|
||||||
directly.
|
directly.
|
||||||
====
|
====
|
||||||
|
@ -36758,16 +36764,16 @@ The above is for use in Spring MVC applications and should be included in the
|
||||||
configuration of a <<mvc-serlvet,DispatcherServlet>>. However, Spring's WebSocket
|
configuration of a <<mvc-serlvet,DispatcherServlet>>. However, Spring's WebSocket
|
||||||
support does not depend on Spring MVC. It is relatively simple to integrate a `WebSocketHandler`
|
support does not depend on Spring MVC. It is relatively simple to integrate a `WebSocketHandler`
|
||||||
into other HTTP serving environments with the help of
|
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].
|
{javadoc-baseurl}/org/springframework/web/socket/server/support/WebSocketHttpRequestHandler.html[WebSocketHttpRequestHandler].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[websocket-server-handshake]]
|
[[websocket-server-handshake]]
|
||||||
==== Customizing the WebSocket Handshake
|
==== Customizing the WebSocket Handshake
|
||||||
The easiest way to customize the initial HTTP WebSocket handshake request is through
|
The easiest way to customize the initial HTTP WebSocket handshake request is through
|
||||||
a `HandshakeInterceptor`, which exposes before and after the handshake methods.
|
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
|
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
|
available to the `WebSocketSession`. For example, there is a built-in interceptor
|
||||||
for passing HTTP session attributes to the WebSocket session:
|
for passing HTTP session attributes to the WebSocket session:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
|
@ -36813,12 +36819,12 @@ And the XML configuration equivalent:
|
||||||
----
|
----
|
||||||
|
|
||||||
A more advanced option is to extend the `DefaultHandshakeHandler` that performs
|
A more advanced option is to extend the `DefaultHandshakeHandler` that performs
|
||||||
the steps of the WebSocket handshake including validating the client origin,
|
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
|
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
|
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
|
adapt to a WebSocket server engine and version that is not yet supported
|
||||||
(also see <<websocket-server-deployment>> for more on this subject).
|
(also see <<websocket-server-deployment>> for more on this subject).
|
||||||
Both the Java config and XML namespace make it possible to configure a custom
|
Both the Java-config and XML namespace make it possible to configure a custom
|
||||||
`HandshakeHandler`.
|
`HandshakeHandler`.
|
||||||
|
|
||||||
|
|
||||||
|
@ -36827,7 +36833,7 @@ Both the Java config and XML namespace make it possible to configure a custom
|
||||||
==== WebSocketHandler Decoration
|
==== WebSocketHandler Decoration
|
||||||
Spring provides a `WebSocketHandlerDecorator` base class that can be used to decorate
|
Spring provides a `WebSocketHandlerDecorator` base class that can be used to decorate
|
||||||
a `WebSocketHandler` with additional behavior. Logging and exception handling
|
a `WebSocketHandler` with additional behavior. Logging and exception handling
|
||||||
implementations are provided and added by default when using the WebSocket Java config
|
implementations are provided and added by default when using the WebSocket Java-config
|
||||||
or XML namespace. The `ExceptionWebSocketHandlerDecorator` catches all uncaught
|
or XML namespace. The `ExceptionWebSocketHandlerDecorator` catches all uncaught
|
||||||
exceptions arising from any WebSocketHandler method and closes the WebSocket
|
exceptions arising from any WebSocketHandler method and closes the WebSocket
|
||||||
session with status `1011` that indicates a server error.
|
session with status `1011` that indicates a server error.
|
||||||
|
@ -36840,10 +36846,10 @@ The Spring WebSocket API is easy to integrate into a Spring MVC application wher
|
||||||
the `DispatcherServlet` serves both HTTP WebSocket handshake as well as other
|
the `DispatcherServlet` serves both HTTP WebSocket handshake as well as other
|
||||||
HTTP requests. It is also easy to integrate into other HTTP processing scenarios
|
HTTP requests. It is also easy to integrate into other HTTP processing scenarios
|
||||||
by invoking `WebSocketHttpRequestHandler`. This is convenient and easy to
|
by invoking `WebSocketHttpRequestHandler`. This is convenient and easy to
|
||||||
understand. However special considerations apply with regards to JSR-356 runtimes.
|
understand. However, special considerations apply with regards to JSR-356 runtimes.
|
||||||
|
|
||||||
The Java WebSocket API (JSR-356) provides two deployment mechanisms. The first
|
The Java WebSocket API (JSR-356) provides two deployment mechanisms. The first
|
||||||
involves a Servlet container classpath scan (Servlet 3 feature) at startup and
|
involves a Servlet container classpath scan (Servlet 3 feature) at startup; and
|
||||||
the other is a registration API to use at Servlet container initialization.
|
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"
|
Neither of these mechanism make it possible to use a single "front controller"
|
||||||
for all HTTP processing -- including WebSocket handshake and all other HTTP
|
for all HTTP processing -- including WebSocket handshake and all other HTTP
|
||||||
|
@ -36867,11 +36873,11 @@ Java WebSocket API.
|
||||||
====
|
====
|
||||||
|
|
||||||
A secondary consideration is that Servlet containers with JSR-356 support
|
A secondary consideration is that Servlet containers with JSR-356 support
|
||||||
are expected to perform an SCI scan that can slow down application startup
|
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
|
in some cases dramatically. If a significant impact is observed after an
|
||||||
upgrade to a Servlet container version with JSR-356 support, it should
|
upgrade to a Servlet container version with JSR-356 support, it should
|
||||||
be possible to selectively enable or disable web fragments (and SCI scanning)
|
be possible to selectively enable or disable web fragments (and SCI scanning)
|
||||||
through the use of an `<absolute-ordering />` element in web.xml:
|
through the use of an `<absolute-ordering />` element in `web.xml`:
|
||||||
|
|
||||||
[source,xml,indent=0]
|
[source,xml,indent=0]
|
||||||
[subs="verbatim,quotes,attributes"]
|
[subs="verbatim,quotes,attributes"]
|
||||||
|
@ -36914,8 +36920,8 @@ Java initialization API, if required:
|
||||||
|
|
||||||
[[websocket-fallback]]
|
[[websocket-fallback]]
|
||||||
=== Fallback Options
|
=== Fallback Options
|
||||||
As explained in the <<websocket-into-fallback-options,introduction>> WebSocket is not
|
As explained in the <<websocket-into-fallback-options,introduction>>, WebSocket is not
|
||||||
supported in all browsers yet or may be precluded by restrictive network proxies.
|
supported in all browsers yet and may be precluded by restrictive network proxies.
|
||||||
This is why Spring provides fallback options that emulate the WebSocket API as close
|
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].
|
as possible based on the https://github.com/sockjs/sockjs-protocol[SockJS protocol].
|
||||||
|
|
||||||
|
@ -36973,7 +36979,7 @@ The above is for use in Spring MVC applications and should be included in the
|
||||||
configuration of a <<mvc-serlvet,DispatcherServlet>>. However, Spring's WebSocket
|
configuration of a <<mvc-serlvet,DispatcherServlet>>. However, Spring's WebSocket
|
||||||
and SockJS support does not depend on Spring MVC. It is relatively simple to
|
and SockJS support does not depend on Spring MVC. It is relatively simple to
|
||||||
integrate into other HTTP serving environments with the help of
|
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].
|
{javadoc-baseurl}/org/springframework/web/socket/sockjs/support/SockJsHttpRequestHandler.html[SockJsHttpRequestHandler].
|
||||||
|
|
||||||
On the browser side, applications can use the
|
On the browser side, applications can use the
|
||||||
https://github.com/sockjs/sockjs-client[sockjs-client] that emulates the W3C
|
https://github.com/sockjs/sockjs-client[sockjs-client] that emulates the W3C
|
||||||
|
@ -36981,7 +36987,7 @@ WebSocket API and communicates with the server to select the best
|
||||||
transport option depending on the browser it's running in. Review the
|
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
|
https://github.com/sockjs/sockjs-client[sockjs-client] page and the list of
|
||||||
transport types supported by browser. The client also provides several
|
transport types supported by browser. The client also provides several
|
||||||
configuration options, for example to specify which transports to include.
|
configuration options, for example, to specify which transports to include.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -36990,7 +36996,7 @@ configuration options, for example to specify which transports to include.
|
||||||
An in-depth description of how SockJS works is beyond the scope of this document.
|
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.
|
This section summarizes a few key facts to aid with understanding.
|
||||||
The SockJS protocol itself is defined in a
|
The SockJS protocol itself is defined in a
|
||||||
https://github.com/sockjs/sockjs-protocol/blob/master/sockjs-protocol-0.3.3.py[test suite]
|
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
|
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]
|
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.
|
showing comments on the right and code on the left.
|
||||||
|
@ -37013,10 +37019,10 @@ 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
|
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.
|
protocol but is added to help in clustered environments.
|
||||||
|
|
||||||
SockJS adds a minimal amount of message framing. For example the server can send
|
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
|
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
|
"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"]+).
|
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
|
By default the server sends a heartbeat frame every 25 seconds to keep proxies
|
||||||
and loadbalancers from timing out the connection.
|
and loadbalancers from timing out the connection.
|
||||||
|
@ -37026,11 +37032,11 @@ and loadbalancers from timing out the connection.
|
||||||
[[websocket-fallback-sockjs-spring]]
|
[[websocket-fallback-sockjs-spring]]
|
||||||
==== Spring's SockJS Support
|
==== Spring's SockJS Support
|
||||||
In the Spring Framework, server-side support for the SockJS protocol is provided through a
|
In the Spring Framework, server-side support for the SockJS protocol is provided through a
|
||||||
hierarchy of classes that implement the `SockJsService` interface while
|
hierarchy of classes that implement the `SockJsService` interface, while
|
||||||
`SockJsHttpRequestHandler` integrates the service into HTTP request processing.
|
`SockJsHttpRequestHandler` integrates the service into HTTP request processing.
|
||||||
|
|
||||||
To implement HTTP streaming and long polling both of which require an HTTP connection
|
To implement HTTP streaming and long polling in Servlet containers (both of which require
|
||||||
to remain open longer than usual, in Servlet containers Spring's SockJS support
|
an HTTP connection to remain open longer than usual), Spring's SockJS support
|
||||||
relies on Servlet 3 async support.
|
relies on Servlet 3 async support.
|
||||||
|
|
||||||
[WARNING]
|
[WARNING]
|
||||||
|
@ -37039,7 +37045,7 @@ Servlet 3 async support does not expose a notification when a client disconnects
|
||||||
e.g. a browser tab is closed, page is refreshed, etc
|
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
|
(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
|
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
|
to the response; at which point the SockJS session will be closed. Since the
|
||||||
SockJsService sends a heartbeat every 25 seconds, typically a disconnected
|
SockJsService sends a heartbeat every 25 seconds, typically a disconnected
|
||||||
client will be detected within that time period.
|
client will be detected within that time period.
|
||||||
====
|
====
|
||||||
|
@ -37060,8 +37066,8 @@ and server both need to understand how to interpret messages.
|
||||||
[[websocket-stomp-overview]]
|
[[websocket-stomp-overview]]
|
||||||
==== Overview of STOMP
|
==== Overview of STOMP
|
||||||
http://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP] is a simple
|
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
|
messaging protocol originally created for scripting languages (such as Ruby, Python and
|
||||||
scripting languages such as Ruby, Python and Perl. It is designed to address a
|
Perl) to connect to enterprise message brokers. It is designed to address a
|
||||||
subset of commonly used patterns in messaging protocols. STOMP can be used over
|
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.
|
any reliable 2-way streaming network protocol such as TCP and WebSocket.
|
||||||
|
|
||||||
|
@ -37076,9 +37082,9 @@ header2:value2
|
||||||
Body^@
|
Body^@
|
||||||
----
|
----
|
||||||
|
|
||||||
For example a client can use the +SEND+ command to send a message or the
|
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
|
+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
|
require a +"destination"+ header that indicates where to send a message to, or likewise
|
||||||
what to subscribe to.
|
what to subscribe to.
|
||||||
|
|
||||||
Here is an example of a client sending a request to buy stock shares:
|
Here is an example of a client sending a request to buy stock shares:
|
||||||
|
@ -37105,9 +37111,10 @@ destination:/topic/price.stock.*
|
||||||
====
|
====
|
||||||
The meaning of a destination is intentionally left opaque in the STOMP spec. It can
|
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
|
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
|
the syntax of the destinations that they support. It is very common however, for
|
||||||
to be path-like strings where "/topic/.." implies publish-subscribe (one-to-many)
|
destinations to be path-like strings where `"/topic/.."` implies publish-subscribe
|
||||||
and "/queue/" to implies point-to-point (one-to-one) message exchanges.
|
(__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.
|
STOMP servers can use the +MESSAGE+ command to broadcast messages to all subscribers.
|
||||||
|
@ -37155,7 +37162,7 @@ The Spring Framework provides support for using STOMP over WebSocket through
|
||||||
the +spring-messaging+ and +spring-websocket+ modules. It's easy to enable it.
|
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
|
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":
|
options. The endpoint is available for clients to connect to at URL path `/portfolio`:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
@ -37233,7 +37240,7 @@ messages are handled within the application.
|
||||||
|
|
||||||
As mentioned in the <<websocket-intro-architecture,introduction>> the
|
As mentioned in the <<websocket-intro-architecture,introduction>> the
|
||||||
`spring-messaging` module contains key abstractions from the
|
`spring-messaging` module contains key abstractions from the
|
||||||
https://spring.io/spring-integration[Spring Integration] project including
|
https://spring.io/spring-integration[Spring Integration] project, including
|
||||||
`Message`, `MessageChannel`, `MessageHandler` and a few others.
|
`Message`, `MessageChannel`, `MessageHandler` and a few others.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
|
@ -37245,23 +37252,23 @@ abstractions and implementations in support of the well-known
|
||||||
EAI patterns (http://www.eaipatterns.com/[enterprise integration patterns]).
|
EAI patterns (http://www.eaipatterns.com/[enterprise integration patterns]).
|
||||||
====
|
====
|
||||||
|
|
||||||
https://github.com/spring-projects/spring-framework/blob/master/spring-messaging/src/main/java/org/springframework/messaging/MessageChannel.java[MessageChannel]
|
{javadoc-baseurl}/org/springframework/messaging/MessageChannel.html[MessageChannel]
|
||||||
is a simple contract for passing messages between components without
|
is a simple contract for passing messages between components without
|
||||||
creating tight coupling among them.
|
creating tight coupling among them.
|
||||||
https://github.com/spring-projects/spring-framework/blob/master/spring-messaging/src/main/java/org/springframework/messaging/SubscribableChannel.java[SubscribableChannel] extends
|
{javadoc-baseurl}/org/springframework/messaging/SubscribableChannel.html[SubscribableChannel] extends
|
||||||
it with the ability to register subscribers and
|
it, with the ability to register subscribers; and
|
||||||
https://github.com/spring-projects/spring-framework/blob/master/spring-messaging/src/main/java/org/springframework/messaging/support/ExecutorSubscribableChannel.java[ExecutorSubscribableChannel]
|
{javadoc-baseurl}/org/springframework/messaging/support/ExecutorSubscribableChannel.html[ExecutorSubscribableChannel]
|
||||||
is an implementation that passes messages to subscribers in
|
is an implementation that passes messages to subscribers in
|
||||||
the same thread or a different thread depending on whether it has been provided with
|
the same thread or a different thread depending on whether it has been provided with
|
||||||
a `java.util.concurrent.Executor`. This enables assembling message
|
a `java.util.concurrent.Executor`. This enables assembling message
|
||||||
handling flows from various components and modifying them through configuration.
|
handling flows from various components and modifying them through configuration.
|
||||||
|
|
||||||
The provided Java config `@EnableWebSocketMessageBroker` and XML namespace
|
The provided Java-config `@EnableWebSocketMessageBroker` and XML namespace
|
||||||
`<websocket:message-broker>` each put together a default message handling
|
`<websocket:message-broker>` each put together a default message handling
|
||||||
flow for applications to use, as explained next. This flow can be modified,
|
flow for applications to use, as explained next. This flow can be modified,
|
||||||
customized, or extended. For example an application can add a
|
customized, or extended. For example, an application can add a
|
||||||
https://github.com/spring-projects/spring-framework/blob/master/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptor.java[ChannelInterceptor]
|
{javadoc-baseurl}/org/springframework/messaging/support/ChannelInterceptor.html[ChannelInterceptor]
|
||||||
to any message channel in order to intercept messages passing through it,
|
to any message channel in order to intercept messages passing through it;
|
||||||
it can register additional message handling components, alternate between
|
it can register additional message handling components, alternate between
|
||||||
synchronous and asynchronous message passing, and so on.
|
synchronous and asynchronous message passing, and so on.
|
||||||
|
|
||||||
|
@ -37269,7 +37276,7 @@ Incoming client STOMP messages are passed to a message channel with the name
|
||||||
`"clientInboundChannel"`. By default the messages are routed to annotated
|
`"clientInboundChannel"`. By default the messages are routed to annotated
|
||||||
methods as well as to a "simple" message broker. This simple message broker
|
methods as well as to a "simple" message broker. This simple message broker
|
||||||
automatically records subscriptions, in-memory, and broadcasts messages as
|
automatically records subscriptions, in-memory, and broadcasts messages as
|
||||||
necessary. As explained later you can also use a full-featured message broker
|
necessary. As explained later, you can also use a full-featured message broker
|
||||||
(e.g. RabbitMQ, ActiveMQ, and any other broker that supports STOMP) to manage
|
(e.g. RabbitMQ, ActiveMQ, and any other broker that supports STOMP) to manage
|
||||||
subscriptions and broadcast messages.
|
subscriptions and broadcast messages.
|
||||||
|
|
||||||
|
@ -37320,12 +37327,12 @@ XML configuration equivalent:
|
||||||
</beans>
|
</beans>
|
||||||
----
|
----
|
||||||
|
|
||||||
The configuration example assigns destination prefixes -- "/app" for filtering
|
The configuration example assigns destination prefixes -- `/app` for filtering
|
||||||
messages to annotated methods and "/topic" for messages to the broker. The
|
messages to annotated methods and `/topic` for messages to the broker. The
|
||||||
examples below demonstrate how this can be used.
|
examples below demonstrate how this can be used.
|
||||||
|
|
||||||
The destination prefix should not be included in annotation mappings. For
|
The destination prefix should not be included in annotation mappings. For
|
||||||
example this method handles messages to destination "/app/greetings":
|
example, this method handles messages to destination `/app/greetings`:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
@ -37345,10 +37352,10 @@ example this method handles messages to destination "/app/greetings":
|
||||||
The method accepts a String extracted from the payload of the message,
|
The method accepts a String extracted from the payload of the message,
|
||||||
possibly converted based on its content type. The method can also return a
|
possibly converted based on its content type. The method can also return a
|
||||||
value, which is wrapped as the payload of a new message and sent to a message
|
value, which is wrapped as the payload of a new message and sent to a message
|
||||||
channel named `"brokerChannel"` used for sending messages to the broker
|
channel named `"brokerChannel"` (which is used for sending messages to the broker
|
||||||
from within the application. The new message is sent to the same destination
|
from within the application). The new message is sent to the same destination
|
||||||
as that of the client message but with the default prefix "/topic"
|
as that of the client message, but with the default prefix `/topic`
|
||||||
(`@SendTo` can be used for any other target destination):
|
(you can also use `@SendTo` for any other target destination):
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
@ -37366,11 +37373,12 @@ as that of the client message but with the default prefix "/topic"
|
||||||
----
|
----
|
||||||
|
|
||||||
As a result, to put it all together, a client sends a greeting message to
|
As a result, to put it all together, a client sends a greeting message to
|
||||||
destination "/app/greetings". The message is routed to `GreetingController`,
|
destination `/app/greetings`. The message is routed to `GreetingController`,
|
||||||
which enriches the greeting with a timestamp and sends a new message to the
|
which enriches the greeting with a timestamp and sends a new message to the
|
||||||
broker with destination "/topic/greetings". The broker then broadcasts the
|
broker with destination `/topic/greetings`. The broker then broadcasts the
|
||||||
message to all subscribed, connected clients.
|
message to all subscribed, connected clients.
|
||||||
|
|
||||||
|
|
||||||
[[websocket-stomp-handle-annotations]]
|
[[websocket-stomp-handle-annotations]]
|
||||||
===== Annotation-based Message Handling
|
===== Annotation-based Message Handling
|
||||||
|
|
||||||
|
@ -37395,8 +37403,8 @@ The presence of the annotation is not required since it is assumed by default.
|
||||||
type conversion using an `org.springframework.core.convert.converter.Converter`
|
type conversion using an `org.springframework.core.convert.converter.Converter`
|
||||||
if necessary.
|
if necessary.
|
||||||
* `@Headers`-annotated method argument that must also be assignable to `java.util.Map`
|
* `@Headers`-annotated method argument that must also be assignable to `java.util.Map`
|
||||||
for access to all headers in the message
|
for access to all headers in the message.
|
||||||
* `MessageHeaders` method argument for getting access to a map of all headers
|
* `MessageHeaders` method argument for getting access to a map of all headers.
|
||||||
* `MessageHeaderAccessor`, `SimpMessageHeaderAccessor`, or `StompHeaderAccessor`
|
* `MessageHeaderAccessor`, `SimpMessageHeaderAccessor`, or `StompHeaderAccessor`
|
||||||
for access to headers via typed accessor methods.
|
for access to headers via typed accessor methods.
|
||||||
* `@DestinationVariable`-annotated arguments for access to template
|
* `@DestinationVariable`-annotated arguments for access to template
|
||||||
|
@ -37413,24 +37421,25 @@ default. An `@SendTo` message level annotation can be used to specify any
|
||||||
other destination instead.
|
other destination instead.
|
||||||
|
|
||||||
An `@SubscribeMapping` annotation can also be used to map subscription requests
|
An `@SubscribeMapping` annotation can also be used to map subscription requests
|
||||||
to `@Controller` methods. It is supported on the method level but can also be
|
to `@Controller` methods. It is supported on the method level, but can also be
|
||||||
combined with a type level `@MessageMapping` annotation that expresses shared
|
combined with a type level `@MessageMapping` annotation that expresses shared
|
||||||
mappings across all message handling methods within the same controller.
|
mappings across all message handling methods within the same controller.
|
||||||
|
|
||||||
By default the return value from an `@SubscribeMapping` method is sent as a
|
By default the return value from an `@SubscribeMapping` method is sent as a
|
||||||
message directly back to the connected client and does not pass through the
|
message directly back to the connected client and does not pass through the
|
||||||
broker. This useful for implementing request-reply message interactions for
|
broker. This is useful for implementing request-reply message interactions; for
|
||||||
example to fetch application data when the application UI is being initialized.
|
example, to fetch application data when the application UI is being initialized.
|
||||||
Or alternatively an `@SubscribeMapping` method can be annotated with `@SendTo`
|
Or alternatively an `@SubscribeMapping` method can be annotated with `@SendTo`
|
||||||
in which case the resulting message is sent to the `"brokerChannel"` using
|
in which case the resulting message is sent to the `"brokerChannel"` using
|
||||||
the specified target destination.
|
the specified target destination.
|
||||||
|
|
||||||
|
|
||||||
[[websocket-stomp-handle-send]]
|
[[websocket-stomp-handle-send]]
|
||||||
===== Sending Messages From Anywhere
|
===== Sending Messages From Anywhere
|
||||||
|
|
||||||
What if you wanted to send messages to connected clients from any part of the
|
What if you wanted to send messages to connected clients from any part of the
|
||||||
application? Any application component can send messages to the `"brokerChannel"`.
|
application? Any application component can send messages to the `"brokerChannel"`.
|
||||||
The easist way to do that is to have a `SimpMessagingTemplate` injected and
|
The easist way to do that is to have a `SimpMessagingTemplate` injected, and
|
||||||
use it to send messages. Typically it should be easy to have it injected by
|
use it to send messages. Typically it should be easy to have it injected by
|
||||||
type, for example:
|
type, for example:
|
||||||
|
|
||||||
|
@ -37459,14 +37468,16 @@ type, for example:
|
||||||
But it can also be qualified by its name "brokerMessagingTemplate" if another
|
But it can also be qualified by its name "brokerMessagingTemplate" if another
|
||||||
bean of the same type exists.
|
bean of the same type exists.
|
||||||
|
|
||||||
|
|
||||||
[[websocket-stomp-handle-simple-broker]]
|
[[websocket-stomp-handle-simple-broker]]
|
||||||
===== Simple Message Broker
|
===== Simple Message Broker
|
||||||
|
|
||||||
The built-in, simple, message broker handles subscription requests from clients,
|
The built-in, simple, message broker handles subscription requests from clients,
|
||||||
stores them in memory, and broadcats messages to connected clients with matching
|
stores them in memory, and broadcasts messages to connected clients with matching
|
||||||
destinations. The broker supports path-like destinations including subscriptions
|
destinations. The broker supports path-like destinations, including subscriptions
|
||||||
to Ant-style destination patterns.
|
to Ant-style destination patterns.
|
||||||
|
|
||||||
|
|
||||||
[[websocket-stomp-handle-broker-relay]]
|
[[websocket-stomp-handle-broker-relay]]
|
||||||
===== Using a Full-Featured Message Broker
|
===== Using a Full-Featured Message Broker
|
||||||
|
|
||||||
|
@ -37474,16 +37485,19 @@ The simple broker is great for getting started but supports only a subset of
|
||||||
STOMP commands (e.g. no acks, receipts, etc), relies on a simple message
|
STOMP commands (e.g. no acks, receipts, etc), relies on a simple message
|
||||||
sending loop, and is not suitable for clustering.
|
sending loop, and is not suitable for clustering.
|
||||||
|
|
||||||
Instead applications can use a full-featured message broker and use it for
|
Instead, applications can use a full-featured message broker and use it for
|
||||||
managing client subscriptions and broadcasting messages.
|
managing client subscriptions and broadcasting messages; while annotated
|
||||||
|
methods can still be used for application processing. In other words, all
|
||||||
|
else remains the same, except a full-featured broker replaces the simple
|
||||||
|
broker.
|
||||||
|
|
||||||
Check the message broker STOMP page (e.g.
|
Check your message broker STOMP documentation (e.g.
|
||||||
http://www.rabbitmq.com/stomp.html[RabbitMQ],
|
http://www.rabbitmq.com/stomp.html[RabbitMQ],
|
||||||
http://activemq.apache.org/stomp.html[ActiveMQ]), install and run the broker with
|
http://activemq.apache.org/stomp.html[ActiveMQ]), install and run the broker with
|
||||||
STOMP support enabled. Then enable the STOMP broker relay in the Spring
|
STOMP support enabled. Then enable the STOMP broker relay in the Spring
|
||||||
configuration as an alternative to the simple broker.
|
configuration as an alternative to the simple broker.
|
||||||
|
|
||||||
Below is example configuration:
|
Below is example configuration that enables use of a full-featured broker:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
@ -37531,42 +37545,55 @@ XML configuration equivalent:
|
||||||
----
|
----
|
||||||
|
|
||||||
The STOMP "broker relay" from the above configuration manages TCP connections
|
The STOMP "broker relay" from the above configuration manages TCP connections
|
||||||
to the external broker, and forwards matching messages to it. Likewise any
|
to the external broker, and forwards messages with matching destination prefixes
|
||||||
messages received from the external broker are matched and routed to connected
|
to it. Likewise, any messages received from the external broker are matched and
|
||||||
clients.
|
routed to connected clients.
|
||||||
|
|
||||||
In effect, messages are now broadcast through a full-featured, robust and
|
In effect, messages are now broadcast through a full-featured, robust and
|
||||||
scalable message broker.
|
scalable message broker.
|
||||||
|
|
||||||
|
|
||||||
[[websocket-stomp-handle-user]]
|
[[websocket-stomp-handle-user]]
|
||||||
===== Handling Messages to User Destinations
|
===== Handling Messages to User Destinations
|
||||||
|
|
||||||
An application can also send messages targeting a specific user.
|
An application can also send messages targeting a specific user.
|
||||||
|
|
||||||
To do so a user must first be authenticated. Although the STOMP `CONNECT` frame
|
To do so a user must first be authenticated. Although the STOMP `CONNECT` frame
|
||||||
has authentication headers when used over WebSocket, it's simpler to use
|
has authentication headers when used over WebSocket, it makes more sense to use
|
||||||
the same HTTP-based authentication already used to secure the application.
|
the same HTTP-based authentication already used to secure the application.
|
||||||
|
|
||||||
An application can use Spring Security for example as usual protecting the
|
For example, an application can use Spring Security as usual to protect HTTP URLs,
|
||||||
HTTP URLs of the STOMP WebSocket endpoint. The authenticanted user will then
|
including paths to STOMP WebSocket endpoint(s). The authenticanted user, based
|
||||||
be added as a header to all messages resulting on that STOMP/WebSocket session.
|
on the value returned from `HttpServletRequest.getUserPrincipal()`, will be
|
||||||
|
saved in the WebSocket session and subsequently added as a header named `user`
|
||||||
|
to all incoming messages for that STOMP/WebSocket session.
|
||||||
|
|
||||||
Spring supports STOMP destinations prefixed with "/user/". For example a client
|
Spring's STOMP support recognizes destinations prefixed with `/user/`.
|
||||||
can subscribe to "/user/position-updates". Such destinations are handled by
|
For example, a client can subscribe to destination `/user/position-updates`.
|
||||||
the `UserDestinationMessageHandler` and transformed into a destination unique
|
This destination will be handled by the `UserDestinationMessageHandler` and
|
||||||
to the user's session, e.g. "/user/position-updates-123". This provides the
|
transformed into a destination unique to the user's session,
|
||||||
convenience of subscribing to a simple destination while also ensuring that it
|
e.g. `/user/position-updates-123`. This provides the convenience of subscribing
|
||||||
doesn't collide with any other user that also subscribes to "/user/position-updates"
|
to a generically named destination, while also ensuring that it doesn't "collide"
|
||||||
in order to receive position updates unique to them.
|
with any other user that also subscribes to `/user/position-updates`
|
||||||
|
in order to receive stock position updates unique to them.
|
||||||
|
|
||||||
Similarly on the sending side, messages can be sent to destination
|
On the sending side, messages can be sent to a destination such as
|
||||||
"/user/{username}/position-updates", which in turn will be translated into the
|
`/user/{username}/position-updates`, which in turn will be translated
|
||||||
destination belonging to the specified user by name.
|
by the `UserDestinationMessageHandler` into the same unique destination
|
||||||
|
belonging to the specified user name.
|
||||||
|
|
||||||
This allows any component within the application to send messages to a specific
|
This allows any component within the application to send messages to a specific
|
||||||
user without necessarily knowing anything more than their name and a generic
|
user without necessarily knowing anything more than their name and a generic
|
||||||
destination.
|
destination.
|
||||||
|
|
||||||
|
When this is used with an external message broker, check the broker documentation
|
||||||
|
on how to manage inactive queues, so that when the user session is over, all
|
||||||
|
unique user queues are removed. For example, RabbitMQ creates auto-delete queues
|
||||||
|
when destinations like `/exchange/amq.direct/position-updates` are used.
|
||||||
|
So in that case the client could subscribe to `/user/exchange/amq.direct/position-updates`.
|
||||||
|
ActiveMQ has http://activemq.apache.org/delete-inactive-destinations.html[configuration options]
|
||||||
|
for purging inactive destinations.
|
||||||
|
|
||||||
|
|
||||||
[[spring-integration]]
|
[[spring-integration]]
|
||||||
= Integration
|
= Integration
|
||||||
|
@ -37589,6 +37616,7 @@ a number of Java EE (and related) technologies.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[remoting]]
|
[[remoting]]
|
||||||
== Remoting and web services using Spring
|
== Remoting and web services using Spring
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue