我有一个简单的网络套接字应用程序,使用跺脚。当用户访问一个页面时,它会自动与服务器建立跺脚连接。用户通过Spring安全进行身份验证。当用户关闭浏览器时,我希望用户自动注销。为此,我创建了一个侦听器来侦听SessionDisconnect tEvent。问题是我没有与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。这可能吗?
现在Spring Session支持WebSockets。按照本指南将其添加到您的项目中。然后,在您的SessionDisconnect tEvent侦听器中,您可以通过以下方式获取您的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();
}
}
(您可以访问的其他标头值:)
header{simpMessageType=CONNECT, stumpCommand=CONNECT,nativeHeaders={X-XSRF-TOKEN=[cb73273e-bff3-4eb7-965d-4c696e22c25a],接受版本=[1.1,1.0],心跳=[10000,10000]},simpSessionAtumtes={HTTP.SESSION.ID=6dd63204-d5ec-4362-8f37-29af5605298d,org.springframework.security.web.csrf.HttpSessionCsrfTokenReposity.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@10b64145,org.springframework.security.web.csrf.CsrfToken=org.springframework.security.web.csrf.DefaultCsrfToken@10b64145},simpHeartbeat=[J@3955ead4,simpSessionId=3x25c1e5}
请务必将其作为bean注册到扩展EXIRingSession的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>();
}
}
我认为你需要一个拦截器,没有它你会得到空的session sionAtbantes
。
您需要在调度器-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(...);
}
这对我有用。
看看下面的帖子。https://spring.io/blog/2014/09/16/preview-spring-security-websocket-support-sessions