2014-11-25 83 views
4

我有一个简单的使用stomp的web套接字应用程序。当用户访问一个页面时,它会自动与服务器建立连接。用户通过弹簧安全进行身份验证。当用户关闭浏览器时,我希望用户自动注销。为此,我创建一个侦听器来侦听SessionDisconnectEvent。问题是我没有与websocket会话相关的httpSession的句柄?是否有想从websocket会话获取httpsession?在春天获取关联的websocket会话的HTTPSession

这里是我的代码:

<websocket:message-broker application-destination-prefix="/test"> 

     <websocket:stomp-endpoint path="/sbapp"> 
      <websocket:handshake-interceptors> 
       <bean class="com.sample.HttpSessionIdHandshakeInterceptor"></bean> 
      </websocket:handshake-interceptors> 
      <websocket:sockjs /> 
     </websocket:stomp-endpoint> 
     <websocket:stomp-broker-relay prefix="/topic,/queue,/user" relay-host="localhost" relay-port="61613"/> 
    </websocket:message-broker> 

,这里是我的WebSocket会话监听器:

@Component 
public class StompDisconnectListener implements ApplicationListener<SessionDisconnectEvent>{ 

    @Override 
    public void onApplicationEvent(SessionDisconnectEvent event) { 

     System.out.println("Stomp disconnect: " + event.getSessionId()); 
    } 
} 

我需要的方式,例如,当我得到得到一个断开事件我手动得到相应的HttpSession然后注销的HttpSession中。这可能吗?

+0

您是否发现这个问题的体面解决方案?在这里碰到相同的用例。 – proulxs 2015-03-10 20:46:45

+0

我也对这个问题的解决方案感兴趣。你最终如何解决它? – Fooble 2016-08-05 03:50:28

回答

2

我想你需要一个拦截器,如果没有它,你会得到空的sessionAttributes

您需要在dispatcher-servlet.xml添加HttpSessionHandshakeInterceptor

<websocket:message-broker 
    application-destination-prefix="/test"> 
    <websocket:stomp-endpoint path="/sbapp"> 
     <websocket:handshake-interceptors> 
      <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> 
     </websocket:handshake-interceptors> 
     <websocket:sockjs session-cookie-needed="true" /> 
    </websocket:stomp-endpoint> 
    <websocket:simple-broker prefix="/topic, /message" /> 
</websocket:message-broker> 

然后你就可以在控制器中获取会话:

@MessageMapping("/authorization.action") 
public Message authorizationAction(
     SimpMessageHeaderAccessor headerAccessor, Message message) { 
    String sessionId = headerAccessor.getSessionId(); 
    Map<String, Object> sessionAttributes = headerAccessor.getSessionAttributes(); 
    System.out.println(sessionId); 
    System.out.println(sessionAttributes); 
    // Do something with session 
    return new Message(...); 
} 

这为我工作。

2

现在Spring会话支持WebSockets。按照this guide将其添加到您的项目。然后,在你SessionDisconnectEvent监听器,你可以得到你HttpSessionID这样:

import org.springframework.context.ApplicationListener; 
import org.springframework.messaging.simp.SimpMessageHeaderAccessor; 
import org.springframework.web.socket.messaging.SessionDisconnectEvent; 

public class WebSocketDisconnectHandler<S> 
    implements ApplicationListener<SessionDisconnectEvent> { 

    public void onApplicationEvent(SessionDisconnectEvent event) { 
    String session = SimpMessageHeaderAccessor.getSessionAttributes(event.getMessage().getHeaders()).get("HTTP.SESSION.ID").toString(); 
    } 
} 

(其它头值,您可以访问:)

headers {simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={X-XSRF-TOKEN=[cb73273e-bff3-4eb7-965d-4c696e22c25a], accept-version=[1.1,1.0], heart-beat=[10000,10000]}, simpSessionAttributes={HTTP.SESSION.ID=6dd63204-d5ec-4362-8f37-29af5605298d, org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CS[email protected]10b64145, org.springframework.security.web.csrf.C[email protected]10b64145}, simpHeartbeat=[[email protected], simpSessionId=3x25c1e5}

一定要登记本作中一个bean扩展ExpiringSession的WebSocket配置文件:

import your.package.WebSocketDisconnectHandler; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.session.ExpiringSession; 

@Configuration 
public class WebSocketHandlersConfig<S extends ExpiringSession> { 

    @Bean 
    public WebSocketDisconnectHandler<S> webSocketDisconnectHandler() { 
     return new WebSocketDisconnectHandler<S>(); 
    } 
}