Bleiben gemeinsam genutzte Web-Worker bei einem erneuten Laden einer einzelnen Seite und einer Linknavigation bestehen?

StackOverflow https://stackoverflow.com/questions/9336774

Frage

Shared Web Workers sind so konzipiert, dass mehrere Seiten von zugelassen werdenDieselbe Site (Herkunft), um einen einzelnen Web Worker freizugeben.

Aus der Spezifikation (oder anderen Tutorials und Informationen zu Shared Workern) ist mir jedoch nicht klar, ob der Shared Worker bestehen bleibt, wenn Sie nur ein Fenster / eine Registerkarte auf der Site haben und zu einer anderen Seite auf derselben Site navigieren.

Dies ist am nützlichsten bei einer WebSocket-Verbindung vom Shared Worker, die während der Navigation auf der Site verbunden bleibt.Stellen Sie sich beispielsweise einen Börsenticker oder Chat-Bereich vor, der auch während der Navigation auf der Website bestehen bleibt (ohne dass das WebSocket erneut verbunden werden muss).

War es hilfreich?

Lösung

Ich habe einige Tests durchgeführt, um die Antwort darauf in der Praxis herauszufinden.

Firefox unterstützt das Erstellen von WebSocket-Verbindungen von Web Workern noch nicht: https:// bugzilla. mozilla.org/show_bug.cgi?id=504553 Firefox ist also erst relevant, wenn dieser Fehler behoben ist.

IE 10 bietet keine Unterstützung für Shared Web Worker und ist daher auch nicht relevant. Damit bleibt Chrome.

Hier ist ein Beispiel zum Testen freigegebener Web-Worker.

Zuerst das 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>

Dann die Implementierung des Shared Workers selbst in 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);

Testergebnisse in Chrome 20 ( die Antwort ):

Wenn die Seite gleichzeitig in zwei separaten Registerkarten geladen wird, steigt die Anzahl der Verbindungen jedes Mal, wenn eine der Seiten neu geladen oder auf den selbstreferenziellen Link geklickt wird.

Wenn nur eine einzelne Instanz der Seite geladen wird, ändert sich die Verbindungsanzahl nie, wenn die Seite neu geladen oder auf den Link geklickt wird.

In Chrome 20: Freigegebene Web-Worker bleiben beim erneuten Laden von Seiten und beim Verknüpfen von Navigationsklicks nicht bestehen.

Andere Tipps

Es scheint, dass dies im Grunde das gleiche Problem ist wie die Frage 'Was passiert mit einem HTML5-Webworker-Thread, wenn der Tab während der Ausführung geschlossen wird?' . Ich denke, der Hauptteil der Spezifikation ist diese Aussage :

Benutzeragenten können das Verarbeitungsmodell "Kill a Worker" für a aufrufen Arbeiter zu jeder Zeit, z.B. als Antwort auf Benutzeranfragen als Antwort auf CPU-Kontingentverwaltung oder wenn ein Mitarbeiter nicht mehr aktiv ist Arbeiter, wenn der Arbeiter auch nach seinem Schließflag weiter ausgeführt wird wurde auf true gesetzt.

Ein aktiver benötigter Arbeiter 'ist wie folgt definiert:

Ein Mitarbeiter wird als aktiv benötigter Mitarbeiter bezeichnet, wenn eines der Dokumente vorhanden ist Objekte in den Dokumenten des Arbeiters sind voll aktiv.

Wenn also nach meinem Verständnis alle Fenster, die auf einen Worker verweisen, geschlossen sind, muss die Spezifikation den Browser vom Browser beenden, jedoch nicht sofort. Abhängig davon ist das Fortbestehen daher unzuverlässig, auch wenn es gelegentlich zu funktionieren scheint.

In Ihrem Beispiel würde mein Ansatz darin bestehen, die gesamte Site von Ajax zu laden. Sie können die Web Worker nicht ausführen, wenn Ihre Benutzer JS deaktiviert haben. Verwenden Sie dann Verlaufs-API , damit die Seitenadresse des Benutzers übereinstimmt die eigentliche Seite (unter Beibehaltung der Suchmaschinen- und Nicht-JS-Kompatibilität).

Ich hatte Erfolg mit einer etwas umständlichen Technik, bei der ich, wenn ich zur nächsten Seite gehen möchte, aber den SharedWorker beibehalten möchte, ein (hoffentlich unauffälliges) Popup-Fenster öffne, das denselben Worker erstellt, darauf warte, dass er aktiv wird, undSenden Sie eine Nachricht an den ursprünglichen Port / das ursprüngliche Fenster, das dann zur neuen Seite navigiert und beim Laden dieser Seite das Popup schließt.Diese Strategie unterhält immer mindestens eine aktive Verbindung, sodass der Mitarbeiter niemals beschließt, die Verbindung zu beenden.

Diese Technik scheint bisher ziemlich robust zu sein.Obwohl das Anzeigen des Popups etwas ärgerlich ist, ist es für einige Anwendungsfälle ein vernünftiger Kompromiss.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top