On this page
6. WebSocket Integration
Spring Session 提供了与 Spring 的 WebSocket 支持的透明集成。
Note
Spring Session 的 WebSocket 支持仅与 Spring 的 WebSocket 支持一起使用。具体来说,它不能直接与JSR-356一起使用。这是由于 JSR-356 没有用于拦截传入的 WebSocket 消息的机制。
6.1 为什么使用 Spring Session 和 WebSockets?
那么,为什么在使用 WebSockets 时需要 Spring Session?
考虑一个通过 HTTP 请求完成其大部分工作的电子邮件应用程序。但是,其中还嵌入了一个可通过 WebSocket API 运行的聊天应用程序。如果用户正在积极地与某人聊天,则我们不应使HttpSession
超时,因为这会带来非常糟糕的用户体验。但是,这正是JSR-356所做的。
另一个问题是,根据 JSR-356,如果HttpSession
超时,则将使用该 HttpSession 创建的任何 WebSocket 超时,并且应强制关闭经过身份验证的用户。这意味着,如果我们正在应用程序中积极地聊天而不使用 HttpSession,那么我们也将断开与对话的连接!
6.2 WebSocket 的用法
WebSocket Sample提供了有关如何将 Spring Session 与 WebSocket 集成的工作示例。您可以按照下面的基本集成步骤进行操作,但是在与自己的应用程序集成时,建议您遵循详细的 WebSocket 指南:
6.2.1 HttpSession 集成
使用 WebSocket 集成之前,应确保首先工作第 5 章,HttpSession 集成。
6.2.2 Spring 配置
在典型的 Spring WebSocket 应用程序中,用户将实现WebSocketMessageBrokerConfigurer
。例如,配置可能类似于以下内容:
@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");
}
}
我们可以轻松地更新配置以使用 Spring Session 的 WebSocket 支持。例如:
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");
}
}
要获得 Spring Session 支持,我们只需要更改两件事:
- (1) 我们没有实现
WebSocketMessageBrokerConfigurer
,而是扩展了AbstractSessionWebSocketMessageBrokerConfigurer
- (2) 我们将
registerStompEndpoints
方法重命名为configureStompEndpoints
AbstractSessionWebSocketMessageBrokerConfigurer
在幕后做什么?
WebSocketConnectHandlerDecoratorFactory
作为WebSocketHandlerDecoratorFactory
添加到WebSocketTransportRegistration
。这样可以确保触发包含WebSocketSession
的自定义SessionConnectEvent
。WebSocketSession
是终止 Spring Session 终止时仍打开的任何 WebSocket 连接所必需的。SessionRepositoryMessageInterceptor
作为HandshakeInterceptor
添加到每个StompWebSocketEndpointRegistration
中。这样可以确保将 Session 添加到 WebSocket 属性以启用更新上次访问时间。SessionRepositoryMessageInterceptor
作为ChannelInterceptor
添加到我们的入站ChannelRegistration
中。这样可以确保每次接收到入站消息时,Spring Session 的上次访问时间都会更新。WebSocketRegistryListener
被创建为 Spring Bean。这样可以确保我们将所有会话 ID Map 到相应的 WebSocket 连接。通过维护此 Map,我们可以在 Spring Session(HttpSession)终止时关闭所有 WebSocket 连接。