<commit_before>= Spring Session - WebSocket
<NAME>
:toc:
:websocketdoc-test-dir: {docs-test-dir}docs/websocket/

This guide describes how to use Spring Session to ensure that WebSocket messages keep your HttpSession alive.

// tag::disclaimer[]

NOTE: Spring Session's WebSocket support only works with Spring's WebSocket support.
Specifically it does not work with using https://www.jcp.org/en/jsr/detail?id=356[JSR-356] directly.
This is due to the fact that JSR-356 does not have a mechanism for intercepting incoming WebSocket messages.

// end::disclaimer[]

== HttpSession Setup

The first step is to integrate Spring Session with the HttpSession. These steps are already outlined in the link:httpsession.html[HttpSession Guide].

Please make sure you have already integrated Spring Session with the HttpSession before proceeding.

// tag::config[]

[[websocket-spring-configuration]]
== Spring Configuration

In a typical Spring WebSocket application users would extend `AbstractWebSocketMessageBrokerConfigurer`.
For example, the configuration might look something like the following:

[source,java]
----
include::{websocketdoc-test-dir}WebSocketConfig.java[tags=class]
----

To hook in the Spring Session support, we need to ensure

* `WebSocketConnectHandlerDecoratorFactory` is added as a `WebSocketHandlerDecoratorFactory` to `WebSocketTransportRegistration`.
This ensures a custom `SessionConnectEvent` is fired that contains the `WebSocketSession`.
The `WebSocketSession` is necessary to terminate any WebSocket connections that are still open when a Spring Session is terminated.
* `SessionRepositoryMessageInterceptor` is added as a `HandshakeInterceptor` to every `StompWebSocketEndpointRegistration`.
This ensures that the Session is added to the WebSocket properties to enable updating the last accessed time.
* `SessionRepositoryMessageInterceptor` is added as a `ChannelInterceptor` to our inbound `ChannelRegistration`.
This ensures that every time an inbound message is received, that the last accessed time of our Spring Session is updated.
* `WebSocketRegistryListener` is created as a Spring Bean.
This ensures that we have a mapping of all of the Session id to the corresponding WebSocket connections.
By maintaining this mapping, we can close all the WebSocket connections when a Spring Session (HttpSession) is terminated.

This is quite a bit of work to get things working.
Fortunately, Spring Session provides a convenience class named `AbstractSessionWebSocketMessageBrokerConfigurer` that hides the complexity of the configuration.
An example is provided below:

.src/main/java/samples/config/WebSocketConfig.java
[source,java]
----
include::{samples-dir}websocket/src/main/java/sample/config/WebSocketConfig.java[tags=class]
----

We only need to change two things to use Spring Session:

<1> Instead of extending `AbstractWebSocketMessageBrokerConfigurer` we extend `AbstractSessionWebSocketMessageBrokerConfigurer`
<2> We rename the `registerStompEndpoints` method to `configureStompEndpoints`

// end::config[]

[[websocket-sample]]
== websocket Sample Application

The websocket sample application demonstrates how to use Spring Session with WebSockets.

=== Running the websocket Sample Application<commit_msg>Small improvement to WebSocket guide<commit_after>= Spring Session - WebSocket
<NAME>
:toc:
:websocketdoc-test-dir: {docs-test-dir}docs/websocket/

This guide describes how to use Spring Session to ensure that WebSocket messages keep your HttpSession alive.

// tag::disclaimer[]

NOTE: Spring Session's WebSocket support only works with Spring's WebSocket support.
Specifically it does not work with using https://www.jcp.org/en/jsr/detail?id=356[JSR-356] directly.
This is due to the fact that JSR-356 does not have a mechanism for intercepting incoming WebSocket messages.

// end::disclaimer[]

== HttpSession Setup

The first step is to integrate Spring Session with the HttpSession. These steps are already outlined in the link:httpsession.html[HttpSession Guide].

Please make sure you have already integrated Spring Session with the HttpSession before proceeding.

// tag::config[]

[[websocket-spring-configuration]]
== Spring Configuration

In a typical Spring WebSocket application users would extend `AbstractWebSocketMessageBrokerConfigurer`.
For example, the configuration might look something like the following:

[source,java]
----
include::{websocketdoc-test-dir}WebSocketConfig.java[tags=class]
----

To hook in the Spring Session support we only need to change two things:

<1> Instead of extending `AbstractWebSocketMessageBrokerConfigurer` we extend `AbstractSessionWebSocketMessageBrokerConfigurer`
<2> We rename the `registerStompEndpoints` method to `configureStompEndpoints`

For example:

.src/main/java/samples/config/WebSocketConfig.java
[source,java]
----
include::{samples-dir}websocket/src/main/java/sample/config/WebSocketConfig.java[tags=class]
----

If interested in more details, here are the things the base class does:

* `WebSocketConnectHandlerDecoratorFactory` is added as a `WebSocketHandlerDecoratorFactory` to `WebSocketTransportRegistration`.
This ensures a custom `SessionConnectEvent` is fired that contains the `WebSocketSession`.
The `WebSocketSession` is necessary to terminate any WebSocket connections that are still open when a Spring Session is terminated.
* `SessionRepositoryMessageInterceptor` is added as a `HandshakeInterceptor` to every `StompWebSocketEndpointRegistration`.
This ensures that the Session is added to the WebSocket properties to enable updating the last accessed time.
* `SessionRepositoryMessageInterceptor` is added as a `ChannelInterceptor` to our inbound `ChannelRegistration`.
This ensures that every time an inbound message is received, that the last accessed time of our Spring Session is updated.
* `WebSocketRegistryListener` is created as a Spring Bean.
This ensures that we have a mapping of all of the Session id to the corresponding WebSocket connections.
By maintaining this mapping, we can close all the WebSocket connections when a Spring Session (HttpSession) is terminated.


// end::config[]

[[websocket-sample]]
== websocket Sample Application

The websocket sample application demonstrates how to use Spring Session with WebSockets.

=== Running the websocket Sample Application
{'fraction_non_alphanumeric': 0.06736242884250475, 'fraction_numerical': 0.003478810879190386, 'mean_word_length': 5.721572794899044, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6636732', 'n_tokens_mistral': 1591, 'n_tokens_neox': 1540, 'n_words': 700}