我正在实现Spring Boot + WebSocket + SockJS应用程序,并且对如何处理HTTP会话/ 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
}
};
更新:
Spring-session处理类似这一问题以及许多其他问题。
答案 0 :(得分:2)
HttpSession
和Websocket
会话是两种不同类型的会话。客户端访问url并完成握手时会创建HttpSession
,而当客户端发送订阅请求时会创建Websocket
会话。
Websocket
会话包含在HttpSession
下。如果HttpSession
超时或无效,则基础Websocket
会话也会断开连接,反之亦然。
为了Websocket
会话配置监听器,HttpSession
监听器将无法监听Websocket
会话事件。对于此类事件,我们需要定义一个扩展org.springframework.web.socket.messaging.SubProtocolWebSocketHandler
类并覆盖afterConnectionEstablished
和afterConnectionClosed
方法的类。看看Javadoc here。
此外,here是一个侦听Spring websocket disconnect事件的示例。您需要配置与此类似的内容。
答案 1 :(得分:0)
HTTP会话假设以保持连接。这就是它的用途。多个连接,同一个会话。在有活动连接时,会话不应过期。