WebSocket 整合
Spring Session 提供與 Spring 的 WebSocket 支援的透明整合。
Spring Session 的 WebSocket 支援僅與 Spring 的 WebSocket 支援配合使用。具體來說,它不能直接使用 JSR-356,因為 JSR-356 沒有攔截傳入 WebSocket 訊息的機制。 |
為何選擇 Spring Session 和 WebSockets?
那麼,當我們使用 WebSockets 時,為何需要 Spring Session?
考慮一個電子郵件應用程式,其大部分工作透過 HTTP 請求完成。但是,其中還嵌入了一個透過 WebSocket API 工作的聊天應用程式。如果使用者正在與某人積極聊天,我們不應該讓 HttpSession
超時,因為這將是一種非常糟糕的使用者體驗。然而,JSR-356 正是這樣做的。
另一個問題是,根據 JSR-356,如果 HttpSession
超時,則應強制關閉使用該 HttpSession
和經過身份驗證的使用者建立的任何 WebSocket 連線。這意味著,如果我們在應用程式中積極聊天但沒有使用 HttpSession,我們也會斷開與對話的連線。
WebSocket 使用
WebSocket 示例提供了一個關於如何將 Spring Session 與 WebSockets 整合的可工作的示例。您可以遵循接下來的幾個標題中描述的基本整合步驟,但我們鼓勵您在與自己的應用程式整合時參考詳細的 WebSocket 指南。
HttpSession
整合
在使用 WebSocket 整合之前,您應首先確保 HttpSession
整合工作正常。
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 支援。以下示例顯示瞭如何做到這一點
@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
被新增為WebSocketTransportRegistration
的一個WebSocketHandlerDecoratorFactory
。這確保會觸發一個包含WebSocketSession
的自定義SessionConnectEvent
。當 Spring Session 結束時,WebSocketSession
對於終止任何仍然開啟的 WebSocket 連線是必要的。 -
SessionRepositoryMessageInterceptor
被新增為每個StompWebSocketEndpointRegistration
的一個HandshakeInterceptor
。這確保Session
被新增到 WebSocket 屬性中,以便更新最後訪問時間。 -
SessionRepositoryMessageInterceptor
被新增為我們的入站ChannelRegistration
的一個ChannelInterceptor
。這確保每當接收到入站訊息時,我們的 Spring Session 的最後訪問時間都會得到更新。 -
WebSocketRegistryListener
被建立為一個 Spring bean。這確保我們擁有所有Session
ID 與相應的 WebSocket 連線的對映。透過維護此對映,當 Spring Session (HttpSession) 結束時,我們可以關閉所有 WebSocket 連線。