# WebSocket Integration

Spring Session provides transparent integration with Spring’s WebSocket support.

|   |Spring Session’s WebSocket support works only with Spring’s WebSocket support.<br/>Specifically,it does not work with using [JSR-356](https://www.jcp.org/en/jsr/detail?id=356) directly, because JSR-356 does not have a mechanism for intercepting incoming WebSocket messages.|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

## Why Spring Session and WebSockets?

So why do we need Spring Session when we use WebSockets?

Consider an email application that does much of its work through HTTP requests.
However, there is also a chat application embedded within it that works over WebSocket APIs.
If a user is actively chatting with someone, we should not timeout the `HttpSession`, since this would be a pretty poor user experience.
However, this is exactly what [JSR-356](https://java.net/jira/browse/WEBSOCKET_SPEC-175) does.

Another issue is that, according to JSR-356, if the `HttpSession` times out, any WebSocket that was created with that `HttpSession` and an authenticated user should be forcibly closed.
This means that, if we are actively chatting in our application and are not using the HttpSession, we also do disconnect from our conversation.

## WebSocket Usage

The [ WebSocket Sample](samples.html#samples) provides a working sample of how to integrate Spring Session with WebSockets.
You can follow the basic steps for integration described in the next few headings, but we encourage you to follow along with the detailed WebSocket Guide when integrating with your own application.

### `HttpSession` Integration

Before using WebSocket integration, you should be sure that you have [`HttpSession` Integration](http-session.html#httpsession) working first.

#### Spring Configuration

In a typical Spring WebSocket application, you would implement `WebSocketMessageBrokerConfigurer`.
For example, the configuration might look something like the following:

```
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/messages").withSockJS();
	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		registry.enableSimpleBroker("/queue/", "/topic/");
		registry.setApplicationDestinationPrefixes("/app");
	}

}
```

We can update our configuration to use Spring Session’s WebSocket support.
The following example shows how to do so:

src/main/java/samples/config/WebSocketConfig.java

```
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session> { (1)

	@Override
	protected void configureStompEndpoints(StompEndpointRegistry registry) { (2)
		registry.addEndpoint("/messages").withSockJS();
	}

	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		registry.enableSimpleBroker("/queue/", "/topic/");
		registry.setApplicationDestinationPrefixes("/app");
	}

}
```

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

|**1**|Instead of implementing `WebSocketMessageBrokerConfigurer`, we extend `AbstractSessionWebSocketMessageBrokerConfigurer`|
|-----|-----------------------------------------------------------------------------------------------------------------------|
|**2**|                      We rename the `registerStompEndpoints` method to `configureStompEndpoints`                       |

What does `AbstractSessionWebSocketMessageBrokerConfigurer` do behind the scenes?

* `WebSocketConnectHandlerDecoratorFactory` is added as a `WebSocketHandlerDecoratorFactory` to `WebSocketTransportRegistration`.
  This ensures a custom `SessionConnectEvent` is fired that contains the `WebSocketSession`.
  The `WebSocketSession` is necessary to end any WebSocket connections that are still open when a Spring Session is ended.

* `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` IDs to the corresponding WebSocket connections.
  By maintaining this mapping, we can close all the WebSocket connections when a Spring Session (HttpSession) is ended.