java - WebSocket 在调用 HttpSessionListener.sessionDestroyed 之前关闭

标签 java spring httpsession spring-websocket

我正在实现一个 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处理像这样的问题和许多其他问题。

最佳答案

HttpSessionWebsocket 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/

相关文章:

java - 来自 JSP 的每个 servlet 请求都会创建新 session 吗?

spring-mvc - 在 Spring MVC 3 中处理后重定向时, session 属性是否显示在 URL 中?

java - jax-rs( Jersey )在 javax.servlet.Filter 中看不到 REMOTE_USER header

java - 在 Spring 上下文中覆盖默认的 OAuth2RestTemplate

Spring Webflux Netty http 和 https

javascript - 如何将文件编码为 base64,然后使用 JS 作为多部分文件上传到后端 api?

session - HttpSession 数据存储在哪里?

java - 有没有办法从每个日志级别的两个单独的 logback.xml 文件配置 logback?

java - 在 Freemarker 中处理 null

java - 如何获得登录我的网络应用程序的所有用户的列表