2012-02-17 16 views
21

Shared Web Workers están diseñados para permitir que varias páginas del mismo sitio (origen) para compartir un solo trabajador Web.Do Web compartido Trabajadores persisten a través de una sola recarga de la página, enlace de navegación

Sin embargo, no me queda claro por la especificación (u otros tutoriales e información sobre Trabajadores Compartidos) si el Trabajador Compartido persistirá si solo tiene una ventana/pestaña del sitio y navega a otra página en el mismo sitio.

Esto sería muy útil en el caso de una conexión WebSocket del Shared Worker que permanece conectado mientras se navega el sitio. Por ejemplo, imagine un cotizador bursátil o un área de chat que persistiría (sin tener que volver a conectar el WebSocket) incluso mientras se navega por el sitio.

+0

Actualmente, el evento de almacenamiento es su mejor opción para eso, los trabajadores compartidos quizás más tarde ... http://stackoverflow.com/questions/19125823/how-is-it-possible-to-share-single-js-resource -between-browser-tabs/19165781 # 19165781 – inf3rno

Respuesta

20

me han hecho algunas pruebas para averiguar la respuesta a esto en la práctica.

Firefox aún no admite la creación de conexiones WebSocket desde Web Workers: https://bugzilla.mozilla.org/show_bug.cgi?id=504553 Por lo tanto, Firefox no es relevante hasta que se resuelva el error.

IE 10 no tiene support for Shared Web Workers por lo que no es relevante tampoco. Entonces eso deja a Chrome.

Aquí se muestra un ejemplo para probar los trabajadores web compartidos.

En primer lugar el código HTML:

<!DOCTYPE html> 
<html> 
<body> 
    <a href="shared.html">reload page</a> 
    <script> 
     var worker = new SharedWorker("shared.js"); 
     worker.port.addEventListener("message", function(e) { 
      console.log("Got message: " + e.data); 
     }, false); 
     worker.port.start(); 
     worker.port.postMessage("start"); 
    </script> 
</body> 
</html> 

A continuación, la aplicación del trabajador compartida sí en shared.js:

var connections = 0; 

self.addEventListener("connect", function(e) { 
    var port = e.ports[0]; 
    connections ++; 
    port.addEventListener("message", function(e) { 
     if (e.data === "start") { 
      var ws = new WebSocket("ws://localhost:6080"); 
      port.postMessage("started connection: " + connections); 
     } 
    }, false); 
    port.start(); 
}, false); 

resultados de las pruebas en Chrome 20 (la respuesta):

Cuando la página se carga simultáneamente en dos pestañas separadas, el recuento de conexiones crece cada vez que una de las páginas se recarga o se hace clic en el enlace autorreferente.

Si solo se carga una instancia de la página, el recuento de conexiones nunca cambia cuando la página se vuelve a cargar o se hace clic en el enlace.

Por lo tanto, en Chrome 20: Los trabajadores web compartidos no persisten en las recargas de página y los clics de navegación de enlace.

+1

+1 para la experimentación – stimms

+0

¿Si vuelvo a cargar la página o abro una nueva, se volverá a crear SharedWorker? Escribo console.log (new Date(). GetTime()); Y el tiempo siempre muestra diferente en la consola, después de la recarga de la página. Así que siempre creé una nueva instancia de WebSocket después de que la página se recarga, ¿correcto? –

4

Parece que este es básicamente el mismo problema que the question 'What happens to an HTML5 web worker thread when the tab is closed while it's running?'. Creo que la parte esencial de la especificación es this statement:

agentes de usuario pueden invocar el modelo de procesamiento de "matar a un trabajador" en un trabajador en cualquier momento, por ejemplo, en respuesta a las peticiones del usuario, en respuesta a gestión de las cuotas de la CPU, o cuando un trabajador deja de ser un activo necesaria trabajador si el trabajador continúa ejecutándose incluso después de su bandera de cierre se establece en true.

Un 'active needed worker' se define como sigue:

Un trabajador se dice que es un trabajador activo necesaria si alguna del Documento objetos en los documentos del trabajador son totalmente activa.

Así que, como yo lo entiendo, si todas las ventanas que hacen referencia a un trabajador se cierran a continuación, el navegador se requiere en las especificaciones para terminar el trabajo, pero no inmediatamente. Dependiendo de que persista, por lo tanto, no será confiable incluso si parece funcionar ocasionalmente.

En su ejemplo, mi enfoque sería cargar todo el sitio por Ajax - no podrá ejecutar Web Workers si sus usuarios tienen JS deshabilitado de todos modos, luego use el History API para hacer la dirección de la página del usuario corresponden a la página real (manteniendo la compatibilidad con el motor de búsqueda y sin JS).

+0

Mi pregunta es si la transición (clic de enlace) de una página a otra en el * mismo sitio * (o una recarga del mismo sitio) mueve al trabajador a una actividad no activa necesaria estado, y si esto hará que sea asesinado. En otras palabras, ¿va de activo a activo o pasa primero a no activo antes de que se cargue la siguiente página (y si es así, es un período suficientemente largo como para importar)? Esta es realmente una pregunta sobre qué hacen los navegadores y cuál es la intención. La redacción de la especificación en sí es ambigua, por lo que estoy preguntando. – kanaka

+1

@kanaka Sí, la descarga de la página lo mueve a un estado donde debería ser eliminado (ver [paso 5] (http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html # run-a-worker)), pero la especificación no requiere que se elimine inmediatamente. Como dije, puede funcionar ocasionalmente, pero no esperes que sea confiable. Si quieres saber qué hacen los navegadores, pruébalo. – robertc

3

He tenido éxito con una técnica algo indirecta por la cual cuando quiero pasar a la página siguiente pero mantener el SharedWorker, abro una ventana emergente (afortunadamente discreta) que crea el mismo trabajador, espere a que se active y envíe un mensaje al puerto/ventana original, que luego navega a la nueva página y luego, cuando esa página se carga, cierra la ventana emergente. Esta estrategia mantiene al menos una conexión activa en todo momento, por lo que el trabajador nunca decide cerrarla.

Esta técnica parece ser bastante robusta hasta el momento. Aunque ver la ventana emergente es algo molesto, es un compromiso razonable para algunos casos de uso.

+0

¿Puede mostrarme su ejemplo, por favor? Siempre estoy creando uno nuevo incluso después de volver a cargar la página. –

Cuestiones relacionadas