2016-03-08 28 views
2

我正在實現Spring Boot + WebSocket + SockJS應用程序,並對如何處理HTTP會話/ Websocket關係有疑問。在HttpSessionListener.sessionDestroyed之前關閉的WebSocket被調用

基本上我希望能夠通知用戶他的會話已經失效(由於超時或因爲已經從另一個位置登錄)。爲此,我希望在框架關閉之前將自己的某個消息放入自己的套接字中。

我轉向了一個http偵聽器,但是我遇到的問題是,在調用HttpSessionListener.sessionDestroyed()的時候,我可以看到該套接字已經被框架關閉了(而不是由於用戶關閉瀏覽器等其他事件)。

有沒有人有任何想法如何實現這一目標?

我有一個非常簡單的Websocket配置,並使用Spring Boot默認運行。

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

    @Override 
    public void configureWebSocketTransport(WebSocketTransportRegistration registration) { 
     registration.setMessageSizeLimit(10000000); 
    } 

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

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

} 

安全部分:

@Configuration 
public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { 

    @Override 
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { 
     applySecurity(messages); 
    } 

    @Override 
    protected boolean sameOriginDisabled() { 
     return true; 
    } 

    private static void applySecurity(MessageSecurityMetadataSourceRegistry messages) { 

     messages.nullDestMatcher().authenticated() // 
       .simpDestMatchers("/app/**").authenticated().simpSubscribeDestMatchers("/user/reply").authenticated() 
       .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll().anyMessage().denyAll(); 

    } 
} 

我的HTTP偵聽器會是這樣的:

return new HttpSessionListener() { 

     @Override 
     public void sessionDestroyed(HttpSessionEvent se) { 
      simpMessagingTemplate.convertAndSendToUser(....); 
     } 

     @Override 
     public void sessionCreated(HttpSessionEvent se) { 
      // no need to do anything when a session is created 
     } 
    }; 

UPDATE:

Spring-session處理這樣一個和許多其他問題。

回答

0

HTTP會話是假設以生存連接。這就是它的目的。多個連接,同一會話。在有活動連接時,會話不應過期。

2

HttpSessionWebsocket會話是兩種不同類型的會話。客戶端訪問url並完成Handshake時會創建HttpSession,而當客戶端發送訂閱請求時會創建Websocket會話。

Websocket會話被包裝在HttpSession。如果HttpSession超時或無效,則底層Websocket會話也會斷開連接,但反之亦然。

即將爲Websocket會話配置監聽器,HttpSession監聽器將無法監聽Websocket會話事件。對於這樣的事件,我們需要定義一個擴展類org.springframework.web.socket.messaging.SubProtocolWebSocketHandler並覆蓋afterConnectionEstablishedafterConnectionClosed方法的類。看看Javadoc here

此外,here是一個監聽Spring websocket斷開事件的示例。你需要配置類似的東西。

+0

謝謝你的信息,但我不確定我們在談論相同。我對監聽websocket會話事件不感興趣,但對http會話事件感興趣。 你說得對,websocket會話綁定到http會話。從這個意義上說,我想通過websocket發送一條消息給用戶:「Hej,你的http會話即將失效,所以準備好......「 之後,http會話將失效,然後websocket將被關閉,但用戶將知道原因。 –

+0

我不確定spring是否允許向特定會話發送消息,看看這個SO回答(http://stackoverflow.com/questions/22367223/sending-message-to-specific-user-on-spring-websocket)。另外,我不認爲有可能從httpsession獲得websocket會話,除非我們手動存儲會話在這個例子中解釋的映射中的id映射 –

+0

我在向用戶發送消息時沒有問題,問題是當HttpsessionListener.sessiondestroyed被調用時,框架已經關閉了web套接字,我不能再使用它了。文檔中說「接收到會話即將失效的通知」,這意味着http會話仍然存在(因此應該是Web套接字會話)howe這是不正確的:網絡套接字連接已關閉。 –

相關問題