我正在实现一个 Spring Boot + WebSocket + SockJS 应用程序,并且对如何处理 HTTP session /Websocket 关系有疑问。
基本上我希望能够通知用户他的 session 已无效(由于超时或因为从其他位置登录)。为此,我想在框架关闭它之前在他自己的套接字中放入特定消息。
我转向 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处理像这样的问题和许多其他问题。
最佳答案
HttpSession
和 Websocket
session 是两种不同类型的 session 。 HttpSession
是在客户端访问url并完成握手时创建的,而Websocket
session 是在客户端发送订阅请求时创建的。
Websocket
session 包装在 HttpSession
下。如果 HttpSession
超时或无效,则底层 Websocket
session 也会断开连接,但反之亦然。
在为 Websocket
session 配置监听器时,HttpSession
监听器将无法监听 Websocket
session 事件。对于此类事件,我们需要定义一个扩展 org.springframework.web.socket.messaging.SubProtocolWebSocketHandler 类并覆盖 afterConnectionEstablished 和 afterConnectionClosed 的类方法。看看Javadoc here .
此外,here是监听 Spring websocket 断开连接事件的示例。您需要配置与此类似的内容。
关于java - WebSocket 在调用 HttpSessionListener.sessionDestroyed 之前关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35856610/