¿Cómo detectar cuándo el navegador acelera los temporizadores y la desconexión de Websockets después de que un usuario abandona una pestaña o apaga la pantalla? (javascript)

12

Contexto

Un juego enviado como una aplicación web progresiva que tiene temporizadores ( setTimeout, setInterval) y conexiones websocket para obtener comunicación en tiempo real.

Qué está pasando

Todo está bien mientras el usuario permanezca en la aplicación. Pero cuando el usuario va a otra pestaña, u otra aplicación o apaga la pantalla (en el caso de los dispositivos móviles), se convierte en un "mundo desconocido infernal".

  • Websockets puede o no "pausarse" o "apagarse"
  • Parece que los temporizadores están siendo estrangulados o rebotados.

Este comportamiento parece depender de los navegadores y la plataforma y, tal vez, incluso depende del comportamiento particular del usuario. Supongo que los navegadores y el sistema operativo tienen su propio ciclo de vida / mecanismos para ahorrar batería y / o computación.

Cuando el usuario regresa, la aplicación se encuentra en un estado desconocido y estoy luchando por restaurar el estado correctamente.

En cuanto a los websockets, tengo una reconexión automática con socket.io y reconectando-websocket, pero no es suficiente para resolver todo.

Buscando respuestas

  • ¿Cuáles son los "ciclos de vida" de los diferentes navegadores con respecto a estos? ¿Está esto documentado? ¿Cuándo deciden apagarse y acelerar?
  • ¿Qué hacen exactamente a los websockets? ¿Los navegadores simplemente los desconectan?
  • ¿Qué hacen exactamente a los temporizadores? ¿Los estrangulan o los rechazan o algo más?
  • ¿Qué sucede con la ejecución de JavaScript en general? ¿Pausado / destruido / estrangulado?
  • ¿Hay alguna manera de conectarse a algún tipo de evento de ciclo de vida del navegador cuando va a apagar las cosas? Lo único que podría encontrar podría ser la API de visibilidad
  • ¿Hay alguna manera de reproducir artificialmente este comportamiento para poder probar soluciones? Es especialmente difícil en el escritorio. Los WebSockets no se pueden desactivar y los desarrolladores de Chrome no parecen tener prisa para ayudar con un problema de 2014 (!): Los WebSockets no se incluyen cuando se usa la limitación de la conexión

  • Independientemente de lo anterior, ¿existe una solución pragmática de navegador cruzado para detectar / resolver este problema? (por ejemplo, por experiencia, Firefox en el escritorio parece comportarse completamente diferente en comparación con Chrome, y un iPhone se desconectará con mucha más frecuencia que un Android)

enlaces relacionados

Kev
fuente
1
Esto es solo un borrador wicg.github.io/page-lifecycle .
norbertpy

Respuestas:

7

No estoy exactamente seguro, pero podría usar trabajadores de servicio. Por lo que sé, se ejecutan en segundo plano incluso si su pestaña no está abierta y se terminan si su pestaña se cierra.

Por cierto. los ciclos de vida de las pestañas del navegador parecen ser diferentes en cada navegador, ya que cada navegador lo maneja de manera diferente. Por lo que veo, el navegador puede congelar pestañas si necesita más memoria para otras cosas.

Aquí están los documentos de Chrome .

Recordé que hay algunos eventos, como onload, que te dicen si un usuario ha abandonado o reabierto la pestaña. Puede usar estos eventos para volver a conectar, etc.

Mointy
fuente
Esta es una idea interesante. ¿Es esto algo que has hecho con algún código para compartir?
Kev
Lo siento, no tengo un código de ejemplo en este momento, pero si busca trabajadores de servicio, hay un montón de tutoriales sobre cómo configurarlos. Lo único que tiene que hacer es colocar un pequeño código donde se conecta a su servidor ws y console.log()cuando recibe mensajes del servidor ws. En Chrome, puede abrir la consola de su trabajador de servicio y así puede probar si los mensajes se renuevan cuando sale de la pestaña.
Mointy
0

Daría diferentes consejos sobre cómo diseñar su aplicación. Por lo que entiendo, su intención es agregar más lógica para comprender si el usuario ya no está activo en el navegador. Esto conlleva un problema diferente que son los detalles del navegador para implementar esa lógica. Con eso en mente, en cambio invertiría en tener un mejor manejo de errores , tanto en el servidor como en el cliente.

Los errores no serán específicos del navegador. Manejarlos hará que su aplicación sea más resistente y agnóstica a los cambios del navegador, lo que eventualmente podría cambiar, por ejemplo, la forma en que hibernan una pestaña, cualquier otra característica que un proveedor pueda implementar en el futuro.

Esta es una idea que puede encontrar en la arquitectura de servicios, pero el mismo patrón se aplica a cualquier aplicación web. Es posible que desee buscar Design-for-Failconceptos:

La complejidad hace inviable suponer robustez por parte de los sistemas en los que se basa. En cambio, uno necesita diseñar sistemas y aplicaciones en cualquier capa dada en la pila de TI para asumir la posibilidad de fallas en niveles más bajos. Design-for-fail requiere pensar en la tolerancia a fallas en todas las capas. Los desarrolladores de aplicaciones ya no pueden limitarse a pensar en la funcionalidad.

https://www.oreilly.com/library/view/designing-delivery/9781491903742/ch04.html

a.m
fuente
¿En qué tipo de "mejor manejo de errores" estás pensando?
Kev