当前位置: 首页 > 知识库问答 >
问题:

WebSocket在HttpSessionListener之前关闭。sessionDestroyed被称为

秦永望
2023-03-14

我正在实现一个Spring Boot WebSocket SockJS应用程序,并对如何处理HTTP会话/WebSocket关系有疑问。

基本上,我希望能够通知用户,他的会话已经无效(因为超时或因为从另一个位置登录)。为此,我想在他自己的套接字中放入一个特定的消息,就在框架关闭它之前。

我转向一个超文本传输协议监听器,但我的问题是,当调用HttpSessionListener.session毁灭()时,我可以看到套接字已经被框架关闭(不是因为其他事件,如用户关闭浏览器)。

有人知道如何做到这一点吗?

我有一个非常简单的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会话处理像这样的问题和许多其他问题。

共有2个答案

仇飞鹏
2023-03-14

HTTP会话应该在连接中存活下来。这就是它的用途。多个连接,同一会话。当有活动连接时,会话不应过期。

秦炜
2023-03-14

当客户端访问url并完成握手时,将创建WebSocket会话,而当客户端发送订阅请求时,将创建WebSocket会话。

Websocket会话被包装在HttpSession下。如果HttpSession超时或无效,则底层Websocket会话也会断开连接,反之亦然。

说到为Websocket会话配置侦听器,HttpSession侦听器将无法侦听Websocket会话事件。对于此类事件,我们需要定义一个扩展org的类。springframework。网状物插座信息。SubtocolWebSocketHandler在建立连接后初始化并重写在连接关闭后重写方法。看看这里的Javadoc。

此外,这里还有一个侦听SpringWebSocket断开连接事件的示例。您需要配置类似于此的内容。

 类似资料:
  • 关闭连接标志着服务器和客户端之间的通信结束。使用事件可以关闭连接,标记通信结束后,服务器和客户端之间无法进一步传输消息。由于连接不良,也可能发生事件。 方法代表再见握手。它终止连接,除非连接再次打开,否则不能交换任何数据。 与前面的示例类似,当用户单击第二个按钮时,调用方法。 也可以传递前面提到的代码和原因说明参数,如下所示。 以下代码完整概述了如何关闭或断开Web Socket连接 - 在浏览器

  • 在使用Hibernate和Jpa的spring boot应用程序中,我需要在saveAll()之前关闭select,以提高高记录数的性能。 我找到了一个使用JPQL的方法,性能很好(在30s内删除+保存10k条记录),但我希望继续使用hibernate和JPA。 我的期望是,当我运行用Java编写的代码时,我必须删除一个表的所有记录,然后保存另一个表的所有记录。当我以经典的方式(deleteAll

  • ap.closeSocket() 关闭 WebSocket 连接。 代码示例 <script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js"></script> <style> .output{ display:block; max-width: 100%; overf

  • 问题内容: 背景 我正在客户端使用HTTP流(服务器推送)情况下的响应。尽管服务器可以通过关闭响应来关闭连接,但是客户端也需要这样做。 问题 客户端在一个单独的线程中处理,如下所示: 因此,当我从发起连接的线程进行调用时(重要的信息是它与处理输入的线程不同),该调用将无限期挂起。我什至把它留了一夜,它仍然挂着。即使打电话也无济于事。 有什么建议吗? 问题答案: 在没有可用字节的情况下,如果不更改读

  • 问题内容: 像这样:类具有一个称为sayHello()的方法。当该类的实例调用sayHello()时,另一个类中的方法会在调用sayHello()之前自动调用。 示例代码可以像这样: 输出结果: 似乎可以通过使用代理模式来完成。但我希望它可以更简单。 使用注释: 然后将MethodListener注释放在Person类中的方法sayHello()上, 调用具有MethodListener批注的方法

  • 问题内容: 在Java 7的try-with-resources中,我不知道finally块和自动关闭发生的顺序。什么顺序 问题答案: 资源在捕获或最终阻塞之前被关闭。请参阅本教程。 try-with-resources语句可以具有catch并最终阻塞,就像普通的try语句一样。在try-with- resources语句中,在声明的资源已关闭之后,将运行任何catch或finally块。 要评估