Java WebSocket在调用HttpSessionListener.sessionDestroyed之前关闭
我正在实现一个Spring Boot+WebSocket+SockJS应用程序,对如何处理HTTP会话/WebSocket关系有疑问 基本上,我希望能够通知用户他的会话已无效(因为超时或从其他位置登录)。为此,我想在框架关闭之前,在他自己的套接字中放入一条特定的消息 我转向了http侦听器,但问题是,在调用Java WebSocket在调用HttpSessionListener.sessionDestroyed之前关闭,java,spring,httpsession,spring-websocket,Java,Spring,Httpsession,Spring Websocket,我正在实现一个Spring Boot+WebSocket+SockJS应用程序,对如何处理HTTP会话/WebSocket关系有疑问 基本上,我希望能够通知用户他的会话已无效(因为超时或从其他位置登录)。为此,我想在框架关闭之前,在他自己的套接字中放入一条特定的消息 我转向了http侦听器,但问题是,在调用HttpSessionListener.sessionDestroyed()时,我可以看到套接字已被框架关闭(不是由于用户关闭浏览器等其他事件) 有人知道如何做到这一点吗 我有一个非常简单的W
HttpSessionListener.sessionDestroyed()
时,我可以看到套接字已被框架关闭(不是由于用户关闭浏览器等其他事件)
有人知道如何做到这一点吗
我有一个非常简单的Websocket配置,并且使用Spring引导默认值运行
@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
}
};
更新:
处理诸如此问题和其他许多问题。HTTP会话应该能够在连接后继续存在。这就是它的目的。多个连接,同一会话。当存在活动连接时,会话不应过期。
HttpSession
和Websocket
会话是两种不同类型的会话HttpSession
是在客户端访问url并完成握手时创建的,而Websocket
会话是在客户端发送订阅请求时创建的
Websocket
会话被包装在HttpSession
下。如果HttpSession
超时或无效,则底层Websocket
会话也会断开连接,反之亦然
说到为Websocket
会话配置侦听器,HttpSession
侦听器将无法侦听Websocket
会话事件。对于此类事件,我们需要定义一个扩展org.springframework.web.socket.messaging.subtocolWebSocketHandler
类的类,并重写afterConnectionEstablished
和afterConnectionClosed
方法。看看Javadoc
此外,还有一个侦听Spring websocket断开连接事件的示例。您需要配置类似的配置。谢谢您提供的信息,但我不确定我们讨论的是相同的。我对侦听websocket会话事件不感兴趣,但对http会话事件感兴趣。websocket会话绑定到http会话的意义是正确的。从这个意义上说,我想通过websocket向用户发送一条消息,比如:“嘿,你的http会话即将失效,所以准备好…”在该消息之后,http会话将失效,然后websocket将关闭,但用户将知道原因。我不确定spring是否允许向特定会话发送消息,看看这个答案()。另外,我认为从httpsession获取websocket会话是不可能的,除非我们像那个例子中解释的那样在映射中手动存储会话id映射。问题是,在调用HttpsessionListener.sessiondestroyed时,框架已经关闭了web套接字,我无法再使用它。文档中说“接收会话即将失效的通知”,这意味着http会话仍然处于活动状态(web套接字会话也应该如此)但事实并非如此:web套接字连接已关闭。即将失效的HTTP会话并不意味着web套接字仍应处于活动状态。两个会话都处于活动状态,当我使HTTP会话失效时,websocket会话似乎在调用sessionDestroyed之前关闭。有没有办法把东西挂在那里?我只希望能够在web套接字中放入“最终”消息。如果我没有错的话,是Spring Security关闭了web套接字(可能是通过WebSocketHandlerDecoratorFactory)