【问题标题】:Spring 4 + Websockets: how to close the session?Spring 4 + Websockets:如何关闭会话?
【发布时间】:2014-11-24 22:00:27
【问题描述】:

我正在使用 Spring 4 + Websockets + Stomp JS 库。 我找不到任何方法来设置 websocket ping/pong 机制(心跳)。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" ...">

<websocket:message-broker>
    <websocket:stomp-endpoint path="/cors/auth/clientEndpoint">
        <websocket:handshake-handler ref="myHandshakeHandler" />
    </websocket:stomp-endpoint>
    <websocket:simple-broker prefix="/queue, /topic" />
    <websocket:client-inbound-channel>
        <websocket:interceptors>
            <bean class="com.mycompany.myproject.utils.messaging.MyInboundChannelInterception"></bean>
        </websocket:interceptors>
    </websocket:client-inbound-channel>
</websocket:message-broker>

<bean id="myHandshakeHandler" class="com.mycompany.myproject.utils.security.MyHandshakeHandler" />

<bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
    <property name="maxSessionIdleTimeout" value="120000" />
</bean>

因此,我正在实现自己的 ping/pong 消息机制。

这里的任务之一 - 如果在超过 10 秒内没有来自客户端的 ping 消息,则实现 websocket 的服务器端关闭。

而且没有办法使用 Spring Websockets 做到这一点!

也许有人可以告诉我如何访问用户的 Session 对象或通过 Spring Websockets 关闭这些 Session?

这里的春天似乎很有限。

【问题讨论】:

    标签: java spring stomp spring-websocket


    【解决方案1】:

    我很惊讶 spring doc 没有提到如何配置服务器 ping...似乎 spring 希望我们阅读代码而不是阅读文档..

    在网上搜索和阅读源代码一段时间后,我意识到它已经被支持,但没有在像 spring websocket doc 这样的显着位置记录。

    我使用的是 spring 4.3.3,这里是如何在不使用 sockJS 的情况下配置服务器 ping:

    @Configuration
    @EnableWebSocketMessageBroker
    public class StompOverWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/ws").setAllowedOrigins("*");
        }
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.setApplicationDestinationPrefixes("/app");
            ThreadPoolTaskScheduler pingScheduler = new ThreadPoolTaskScheduler();
            pingScheduler.initialize();
            registry.enableSimpleBroker("/topic")
                .setHeartbeatValue(new long[]{20000, 0}).setTaskScheduler(pingScheduler);
        }
    ....
    }
    

    并且应该确保你正确设置了 web socket session timeout,它应该大于 ping 间隔,像这样:

    <bean id="servletServerContainerFactoryBean" class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
        <property name="maxSessionIdleTimeout" value="30000"/>
    </bean>
    

    【讨论】:

      【解决方案2】:

      要访问 websocket 会话,您可以使用以下方法: https://stackoverflow.com/a/32270216/2982835

      【讨论】:

        【解决方案3】:

        在这种情况下,在您的应用中配置 SockJS 可能会有很长的路要走:

        <websocket:stomp-endpoint path="/cors/auth/clientEndpoint">
          <websocket:handshake-handler ref="myHandshakeHandler" />
          <websocket:sockjs/>
        </websocket:stomp-endpoint>
        

        这会给你:

        如果您想真正从 STOMP 端点关闭会话,那么我建议您投票/关注the SPR-12288 JIRA issue

        【讨论】:

        • 布莱恩,感谢您的回复。没有sockJs就不能实现心跳管理吗?我的应用程序专为绝对支持 websockets 的现代浏览器而设计。结果,sockJs 在我的情况下是无用的,因为我不需要 websocket 仿真/回退。
        • 您可以手动设置它并检查它是如何在框架中完成的(我们使用 TaskScheduler 定期发送心跳)。 SockJS 不会在这里减慢您的速度,它会尽可能选择可用的最佳传输方式(websocket)。不要忘记,即使您的客户端支持 websockets,网络(HTTP 代理和其他)也可能对 websockets 这样的持久连接不满意。
        • 好的,知道了。谢谢!不确定这个说法:“不要忘记,即使您的客户端支持 websockets,网络(HTTP 代理和其他)也可能对 websockets 等持久连接不满意。”。有官方证明吗?为什么这么重?
        • 参见 Spring 文档:docs.spring.io/spring-framework/docs/4.1.1.RELEASE/… - 基本上使用 SockJS,如果 websocket 工作,它只是普通的 websocket;所以你并没有真正失去任何东西,它不会更重或性能更低。
        • @BrianClozel jira.spring.io/browse/SPR-12288 说 Spring 已经支持从服务器端关闭 websocket。但我找不到文件。你能帮帮我吗?
        猜你喜欢
        • 1970-01-01
        • 2015-01-27
        • 2010-12-06
        • 2013-09-10
        • 2018-11-26
        • 2015-03-27
        • 2014-10-20
        • 2016-10-26
        • 2016-05-31
        相关资源
        最近更新 更多