Сохраняются ли общие веб-работники при перезагрузке одной страницы, переходе по ссылкам - PullRequest
22 голосов
/ 18 февраля 2012

Общие веб-работники предназначены для того, чтобы несколько страниц с одного сайта (источника) могли совместно использовать одного веб-работника.

Однако из спецификации (или других учебников и информации о Shared Workers) мне неясно, будет ли Shared Worker сохраняться, если у вас есть только одно окно / вкладка с сайта и вы переходите на другую страницу на том же сайте .

Это было бы наиболее полезно в случае подключения через WebSocket от Shared Worker, которое остается подключенным во время навигации по сайту. Например, представьте биржевой тикер или область чата, которая сохранится (без необходимости повторного подключения WebSocket) даже во время навигации по сайту.

Ответы [ 3 ]

23 голосов
/ 10 августа 2012

Я провел некоторое тестирование, чтобы найти ответ на этот вопрос на практике.

Firefox пока не поддерживает создание подключений WebSocket из Web Workers: https://bugzilla.mozilla.org/show_bug.cgi?id=504553 Так что Firefox не имеет отношения к этой ошибке

IE 10 не поддерживает Shared Web Workers , поэтому это тоже не актуально.Таким образом, это оставляет Chrome.

Вот пример для тестирования общих веб-работников.

Сначала 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>

Затем реализация самой совместной работы в 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);

Результаты теста в Chrome 20 ( ответ ):

Когда страница загружается одновременно на двух отдельных вкладках, число соединений увеличивается с каждымвремя перезагрузки одной из страниц или щелчка по ссылочной ссылке.

Если загружен только один экземпляр страницы, то число подключений никогда не изменяется при перезагрузке страницы или нажатии на ссылку.

Итак, в Chrome 20: Общие веб-работники не сохраняются при перезагрузках страницы и переходах по ссылкам навигации .

5 голосов
/ 18 февраля 2012

Похоже, что это в основном та же проблема, что и вопрос «Что происходит с рабочим потоком в HTML5, когда вкладка закрыта во время работы?» . Я думаю, что ключевой частью спецификации является это утверждение :

Пользовательские агенты могут вызывать модель обработки «убить рабочего» в работник в любое время, например в ответ на запросы пользователей, в ответ на Управление квотами процессора или когда работник перестает быть активным работник, если работник продолжает выполнение даже после своего флага закрытия был установлен в true.

' активный необходимый работник ' определяется следующим образом:

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

Итак, насколько я понимаю, если все окна, ссылающиеся на работника, закрыты, то спецификация браузера требует завершения работника, но не сразу. Поэтому в зависимости от этого сохранение будет ненадежным, даже если кажется, что оно иногда срабатывает.

В вашем примере мой подход будет состоять в том, чтобы загрузить весь сайт с помощью Ajax - вы не сможете запускать Web Workers, если у ваших пользователей все равно отключен JS, тогда используйте History API чтобы адрес страницы пользователя соответствовал фактической странице (поддерживая совместимость с поисковой системой и не-JS).

3 голосов
/ 28 марта 2013

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

Эта техника пока выглядит достаточно надежной.Хотя всплывающее окно несколько раздражает, в некоторых случаях это разумный компромисс.

...