websockets que org example cliente java javascript google-chrome jetty websocket

java - que - conexión de cierre websocket automáticamente



websocket java tomcat 8 example (9)

Estoy construyendo una aplicación en Java que tiene un servidor websocket incorporado basado en embarcadero. El cliente es la implementación predeterminada de websocket en google chrome. Todo funciona bien, solo si no hay transferencia entre el servidor y el cliente después de un cierto tiempo de que la conexión se cierre. No estoy seguro de quién está cerrando la conexión: el servidor del embarcadero o el navegador Chrome.

La solución a esto, creo, es enviar un mensaje cada x segundos, pero estoy abierto a mejores soluciones.

ASÍ ... mis preguntas son:

  1. ¿Esto es algo que requiere el protocolo websocket y en este caso el navegador Chrome está cerrando mi conexión?

  2. ¿Esto es algo que está más relacionado con el muelle y tiene más o menos que ver con el protocolo websocket? En este caso, ¿cómo desactivo esto en el embarcadero?

  3. ¿Hay algún otro problema?

Gracias

ACTUALIZACIÓN: incluso si envío 1 mensaje / segundo todavía la conexión está cerrada


Acabo de encontrar la solución para esto por mí mismo. Lo que desea establecer es maxIdleTime of WebSocketServlet, en millis. Cómo hacerlo depende de cómo configures tu servlet. Con Guice ServletModule puedes hacer algo como esto por tiempo de espera de 10 horas:

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

Cualquier cosa <0 es tiempo inactivo infinito, creo.


Aquí hay un ejemplo de cómo configurar el tiempo de espera de websocket de Jetty (el culpable más probable) usando WebSocketServlet (en scala, lo siento, pero la sintaxis es más o menos la misma).

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]) } }


Creo que este tiempo de espera que estás experimentando es en realidad parte de TCP / IP y la solución es simplemente enviar mensajes vacíos de vez en cuando.


Creo que esto es un problema de Jetty. No he visto ningún navegador que cierre las conexiones de WebSocket debido a la inactividad ni me he encontrado con otros servidores WebSocket que excedan las conexiones de WebSocket.

Jetty está (estaba) principalmente enfocado en construir servlets de aplicaciones basados ​​en HTTP. En ese contexto, las conexiones HTTP deben limpiarse bastante agresivamente y HTTP no fue diseñado para conexiones de larga duración, por lo que es razonable tener un corto tiempo de espera predeterminado.

No he visto el problema preciso que describió (cerrando incluso con actividad) pero sí veo conexiones WebSocket cerradas después de 30 segundos de inactividad. Es posible que en versiones anteriores de Jetty o en la versión actual por alguna otra razón, la actividad WebSocket no restablezca el temporizador. Lo soluciono utilizando el método setMaxIdleTime en mi objeto BlockingChannelConnector para establecer el valor de tiempo de espera en Integer MAX_VALUE.


En realidad, puede establecer el intervalo de tiempo de espera en la configuración del lado del servidor Jetty utilizando la instancia WebSocketServletFactory. Por ejemplo:

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


En respuesta a su tercera pregunta: su cliente quiere ser capaz de hacer frente a los problemas de red temporales de todos modos, por ejemplo, digamos que el usuario cierra su computadora portátil entre reuniones que la hibernan, o la red simplemente se apaga temporalmente.

La solución es escuchar los eventos onclose en el cliente de socket web y, cuando ocurren, establecer un tiempo de espera del cliente para volver a abrir la conexión, digamos en un segundo:

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


Encontré otra solución bastante rápida y sucia. Si utiliza el enfoque de bajo nivel para implementar WebSocket e Implementa el método onOpen usted mismo, recibirá un objeto que implementa la interfaz WebSocket.Connection . Este objeto tiene un método setMaxIdleTime que puedes ajustar.



Tengo una experiencia similar y creo que podría ser el navegador el que corte la sesión. También configuré maxIdleTimeout, pero la sesión se elimina independientemente. Para mí, parece que es el cliente (el navegador) el que está agotando la sesión y luego cuelga.

No sé cómo evitarlo.