WebSocket 整合
Spring Session 提供與 Spring 的 WebSocket 支援的透明整合。
Spring Session 的 WebSocket 支援僅適用於 Spring 的 WebSocket 支援。具體來說,它不適用於直接使用 JSR-356,因為 JSR-356 沒有攔截傳入 WebSocket 訊息的機制。 |
為何需要 Spring Session 和 WebSocket?
那麼,當我們使用 WebSocket 時,為何需要 Spring Session?
考慮一個電子郵件應用程式,它的大部分工作是透過 HTTP 請求完成的。但是,其中也嵌入了一個透過 WebSocket API 運作的聊天應用程式。如果使用者正在積極地與某人聊天,我們不應該讓 HttpSession
超時,因為這會是非常糟糕的使用者體驗。然而,這正是 JSR-356 所做的。
另一個問題是,根據 JSR-356,如果 HttpSession
超時,則任何使用該 HttpSession
和已驗證使用者建立的 WebSocket 都應強制關閉。這表示,如果我們在應用程式中積極聊天,且未使用 HttpSession,我們也會從對話中斷線。
WebSocket 用法
WebSocket 範例 提供了一個關於如何將 Spring Session 與 WebSocket 整合的工作範例。您可以遵循接下來幾個標題中描述的基本整合步驟,但我們鼓勵您在與自己的應用程式整合時,同時參考詳細的 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 | 我們擴充 AbstractSessionWebSocketMessageBrokerConfigurer ,而不是實作 WebSocketMessageBrokerConfigurer |
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 建立。這確保了我們擁有所有Session
ID 對應到相應 WebSocket 連線的映射。透過維護此映射,我們可以在 Spring Session (HttpSession) 結束時關閉所有 WebSocket 連線。