Spring 4 + Websockets: как закрыть сеанс?

Я использую библиотеку Spring 4 + Websockets + Stomp JS. Я не смог найти способ настроить механизм 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>

As result, I am implementing my own mechanism of ping/pong messages.

Одна из задач здесь - реализовать закрытие вебсокета на стороне сервера в случае отсутствия пинга от клиента более 10 секунд.

И нет способа сделать это с помощью Spring Websockets!

Может быть, кто-нибудь может сказать мне, как получить доступ к объекту сеанса пользователя или закрыть этот сеанс через Spring Websockets?

Кажется, весна здесь очень ограничена.


person walv    schedule 30.09.2014    source источник


Ответы (3)


В этом случае настройка SockJS в вашем приложении может иметь большое значение:

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

Это даст вам:

Если вы действительно хотите закрыть сеанс с конечных точек STOMP, я предлагаю вам проголосовать за SPR- 12288 Проблема JIRA.

person Brian Clozel    schedule 01.10.2014
comment
Брайан, спасибо за ответ. Разве невозможно добиться управления сердцебиением без sockJs? Мое приложение предназначено для современных браузеров, которые определенно поддерживают веб-сокеты. В результате sockJs в моем случае бесполезен, потому что мне не нужна эмуляция/откат веб-сокета. - person walv; 02.10.2014
comment
Вы можете настроить это вручную и проверить, как это делается во фреймворке (мы используем TaskSchedulers для периодической отправки тактов). SockJS не замедлит вас здесь, он выберет лучший доступный транспорт (веб-сокет), если это возможно. Не забывайте, что даже если ваши клиенты поддерживают веб-сокеты, сеть (HTTP-прокси и другие) может быть недовольна постоянными соединениями, такими как веб-сокеты. - person Brian Clozel; 02.10.2014
comment
Хорошо понял. Спасибо! Не уверен в этом утверждении: не забывайте, что даже если ваши клиенты поддерживают веб-сокеты, сеть (прокси-серверы HTTP и другие) могут быть недовольны постоянными соединениями, такими как веб-сокеты. Какие-либо официальные доказательства этого? Почему он тяжелый? - person walv; 03.10.2014
comment
См. документацию Spring: docs.spring.io/spring-framework/docs/4.1.1.RELEASE/ - в основном с SockJS, если работает веб-сокет, это просто веб-сокет; так что вы ничего не теряете, в любом случае он не тяжелее и не менее производительный. - person Brian Clozel; 03.10.2014
comment
@BrianClozel jira.spring.io/browse/SPR-12288 сказал, что Spring поддерживает закрыть websocket со стороны сервера. Но не могу найти документ. Вы можете помочь мне? - person Haozhe Xie; 22.05.2015
comment
@BrianClozel, как отправить пульс с помощью TaskScheduler? можете привести пример? пожалуйста - person zhaozhi; 26.01.2016

Я удивлен, что в весеннем документе не упоминается, как настроить пинг сервера ... Кажется, весна ожидает, что мы будем читать код, а не читать документ.

после некоторого времени поиска в сети и чтения исходного кода я понимаю, что он уже поддерживается, но не задокументирован в заметном месте, например, в spring websocket doc.

Я использую Spring 4.3.3, и вот как настроить пинг сервера без использования sockJS:

@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);
    }
....
}

и должен убедиться, что вы правильно установили время ожидания сеанса веб-сокета, оно должно быть больше, чем интервал ping, например:

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

Для доступа к сеансу веб-сокета вы можете использовать следующий подход: https://stackoverflow.com/a/32270216/2982835

person isaranchuk    schedule 10.03.2015