весенняя паутина закрывается через 30 минут - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь реализовать websocket на основе spring-boot (1.5.13).Обмен сообщениями работает нормально, но через 30 минут соединение прерывается сервером (причина 1008).Я пытался установить различные таймауты, но, похоже, не имеет никакого эффекта.

WebSocketHandler

@Service
@RequiredArgsConstructor
@Slf4j
public class OCPPSocketHandler extends TextWebSocketHandler {

    @Override
    public void handleTextMessage(WebSocketSession webSocketSession, TextMessage textMessage)
        throws IOException {
      ...
    }
}

WebSocketConfig

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    public static final String ENDPOINT = "/pp/v2.0";

    @Autowired
    private CustomSocketHandler socketHandler;

    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new CustomExceptionWebSocketHandlerDecorator(socketHandler),
                ENDPOINT)
                .setAllowedOrigins("*");
    }
}

application.properties:

#6h as milliseconds
server.connection-timeout=3600000 
server.servlet.session.timeout=6h

TextMessage (WebSocket) отправляется каждые 30 минут, чтобы поддерживать соединение.

Я видел сообщение о Настройки тайм-аута Springsocket , но я могуне вижу решения.

Ответы [ 2 ]

0 голосов
/ 29 июля 2019

Я обнаружил, что мой WebSocket закрыт через 30 минут.

Основная причина заключается в том, что сеанс http по умолчанию закрывается через 30 минут в SpringBoot.

В свойстве конфигурации SpringBoot server.servlet.session.timeout изменит поведение по умолчанию, но может иметь некоторыепредел .

Кроме того, в соединениях WebSocket есть сообщения для пинг-понга, поэтому соединение никогда не должно закрываться, пока пинг-понг не прекратится.

После некоторой трассировки я нашел способ решить эту проблему:

  1. Таймер для закрытия соединения находится здесь io.undertow.server.session.InMemorySessionManager.SessionImpl в моем случае.
  2. Как мы видим, io.undertow.server.session.InMemorySessionManager.SessionImpl#setMaxInactiveInterval сбросит таймер.
  3. Этот метод будетбыть вызванным javax.servlet.http.HttpSession#setMaxInactiveInterval.
  4. Итак, если setMaxInactiveInterval вызывается перед каждым тайм-аутом, соединение никогда не будет закрыто.

Вот моя реализация:

  1. Сохраните HandshakeRequest в javax.websocket.EndpointConfig#getUserProperties в Конфигураторе javax.websocket.server.ServerEndpointConfig.Configurator#modifyHandshake
  2. Наши клиенты будут отправлять строковые сообщения, чтобы сохранить работоспособность, в методе onMessageвозьмите HandshakeRequest из javax.websocket.Session#getUserProperties, затем
HttpSession httpSession = (HttpSession) handshakeRequest.getHttpSession();
httpSession.setMaxInactiveInterval((int) (session.getMaxIdleTimeout() / 1000));

Вот и все, надеюсь, это поможет.

0 голосов
/ 29 мая 2018

Соединение может быть закрыто, если оно установлено между сервером или клиентом, а также с помощью брандмауэра, если он отмечает, что на установленном соединении нет активности.

Поэтому необходимо проверить тайм-аут также насторона клиента.Разумно предположить, что для этого типа соединения по умолчанию используется 30 минут, поэтому на стороне клиента используются значения по умолчанию.

Кроме того, рекомендуется периодически проверять состояние соединения, чтобыПример отправки сообщения типа ping (сообщение от клиента) / pong (ответ от сервера).Например, если вы делаете это каждую минуту, у вас есть представление о состоянии соединения, и соединение никогда не будет закрыто из-за неактивности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...