Подтвердить что ты не робот

Автоматическое закрытие соединения

Я создаю приложение в java, у которого есть встроенный сервер websocket, основанный на причале. Клиент - это реализация websocket по умолчанию в google chrome. Все работает нормально, только если между сервером и клиентом нет передачи через определенное время, соединение закрывается. Я не уверен, кто закрывает соединение: сервер причала или браузер Chrome.

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

SO... мои вопросы:

  • Это то, что требует протокол websocket, и в этом случае браузер Chrome закрывает мое соединение?

  • Является ли это нечто более связанным с причалом и более или менее связано с протоколом websocket? В этом случае как отключить это в причале?

  • Есть ли другая проблема?

Спасибо

ОБНОВЛЕНИЕ: даже если я отправляю 1 сообщение в секунду, соединение закрывается

4b9b3361

Ответ 1

В ответ на третий вопрос: ваш клиент хочет в любом случае справиться с временными сетевыми проблемами, например. скажем, пользователь закрывает свой ноутбук между встречами, которые спящий с ним, или сеть просто временно отключается.

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

function setupWebSocket(){
    this.ws = new WebSocket('wss://host:port/path');
    this.ws.onerror = ...;
    this.ws.onopen = ...;
    this.ws.onmessage = ...;
    this.ws.onclose = function(){
        setTimeout(setupWebSocket, 1000);
    };
}

Ответ 3

Я нашел другое, довольно быстрое и грязное решение. Если вы используете низкоуровневый подход для реализации WebSocket и сами внедряете метод onOpen, вы получаете объект, реализующий интерфейс WebSocket.Connection. Этот объект имеет метод setMaxIdleTime, который вы можете настроить.

Ответ 4

Фактически вы можете установить интервал ожидания в конфигурации на стороне сервера Jetty, используя экземпляр WebSocketServletFactory. Например:

WebSocketHandler wsHandler = new WebSocketHandler() {
    @Override
    public void configure(WebSocketServletFactory factory) {
        factory.getPolicy().setIdleTimeout(1500);
        factory.register(MyWebSocketAdapter.class);
        ...
    }
}

Ответ 5

Просто нашел решение для себя. То, что вы хотите установить, - maxIdleTime для WebSocketServlet, в миллисекундах. Как это сделать, зависит от того, как вы настраиваете свой сервлет. С Guice ServletModule вы можете сделать что-то подобное для тайм-аута 10 часов:

serve("ws").with(MyWSServlet.class, 
new HashMap<String, Sring>(){{ put("maxIdleTime", TimeUnit.HOURS.toMillis(10) + ""); }});

Все, что угодно и lt 0 - бесконечное время простоя, я полагаю.

Ответ 6

Я считаю, что это проблема Jetty. Я не видел, чтобы какие-либо браузеры закрывали соединения WebSocket из-за неактивности, и я не встречал других серверов WebSocket, которые не встречали соединения WebSocket.

Jetty (в основном) сосредоточен на создании сервлетов приложений на основе HTTP. В этом контексте HTTP-соединения должны быть очищены довольно агрессивно, а HTTP не предназначен для долговременных подключений, поэтому наличие короткого тайм-аута по умолчанию является разумным.

Я не видел точной проблемы, которую вы описали (закрытие даже с активностью), но я вижу, что соединения WebSocket закрываются через 30 секунд бездействия. Возможно, что в старых версиях Jetty или в текущей версии по какой-то другой причине таймер не является reset по активности WebSocket. Я обойду это, используя метод setMaxIdleTime на моем объекте BlockingChannelConnector, чтобы установить значение таймаута в Integer MAX_VALUE.

Ответ 7

Я думаю, что этот тайм-аут, который вы испытываете, на самом деле является частью TCP/IP, и решение состоит в том, чтобы просто отправлять пустые сообщения время от времени.

Ответ 8

Вот пример того, как настроить тайм-аут веб-сервера Jetty (наиболее вероятный виновник) с помощью WebSocketServlet (в scala, извините, но синтаксис почти такой же).

import javax.servlet.annotation.WebServlet
import org.eclipse.jetty.websocket.servlet.{WebSocketServletFactory, WebSocketServlet}

@WebServlet(name = "WebSocket Servlet")
class WebsocketServlet extends WebSocketServlet {
  override def configure(factory: WebSocketServletFactory): Unit = {
    factory.getPolicy.setIdleTimeout(1000 * 3600)
    factory.register(classOf[ClientWebsocket])
  }
}

Ответ 9

У меня есть аналогичный опыт, и я считаю, что это может быть браузер, который сокращает сессию. Я также устанавливаю maxIdleTimeout, но сеанс отключается независимо. Для меня, похоже, что клиент (браузер) синхронизирует сеанс и затем вешает трубку.

Не знаю, как обойти это.

Ответ 10

Та же проблема: использовались WebSockets & Библиотека sockjs-client/1.0.3/sockjs с @ServerEndPoint на стороне Java-сервера. Соединения веб-сокетов продолжали разрываться.

Я перешел на использование Stomp и sockJS (отказавшись от @ServerEndpoint), но столкнулся с другой проблемой, популярной в SO -/info = 34424 - с ошибкой 404 -

Мне пришлось отказаться от использования XML-подхода библиотеки Stomp Spring, как это было предложено в других местах. В моем проекте Spring 4.2, и многие реализации SockJS Stomp обычно хорошо работают с реализациями Spring Boot. Эта реализация от Baeldung сработала (у меня без перехода с Spring 4.2 на 5).

После использования зависимостей, упомянутых в его блоге, он все равно дал мне ClassNotFoundError. Я добавил ниже зависимость, чтобы исправить это.

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>

Ответ 11

Это работало для меня, в то время как другие решения не были!

  1. Обновите свои юпитеры
  2. Запустите Jupyters через предпочитаемую тетрадь или лабораторию, но добавьте этот код в конце строки в консоли: & lt; - no-browser>

Это останавливает необходимость постоянного подключения к вашему экземпляру EC2. Поэтому, даже если вы потеряете соединение из-за потери интернет-соединения, всякий раз, когда вы получаете новый доступ к Wi-Fi, он автоматически повторно подключается к активно работающему ядру.

Кроме того, не забудьте запустить свой jupyter с учетной записью tmux или ngnix или в других подобных средах.

Надеюсь это поможет!