Pergunta

Trabalhadores da Web compartilhados são projetados para permitir várias páginas deo mesmo site (origem) para compartilhar um único Web Worker.

No entanto, não está claro para mim a partir das especificações (ou outros tutoriais e informações sobre trabalhadores compartilhados) se o trabalhador compartilhado persistirá se você tiver apenas uma janela / guia do site e navegar para outra página no mesmo site.

Isso seria mais útil no caso de uma conexão WebSocket do trabalhador compartilhado que permanece conectado enquanto o site é navegado.Por exemplo, imagine um ticker da bolsa ou área de bate-papo que persistiria (sem a necessidade de reconectar o WebSocket) mesmo enquanto o site fosse navegado.

Foi útil?

Solução

Fiz alguns testes para descobrir a resposta para isso na prática.

O Firefox ainda não oferece suporte à criação de conexões WebSocket de Web Workers: https:// bugzilla. mozilla.org/show_bug.cgi?id=504553 Portanto, o Firefox não é relevante até que o bug seja resolvido.

O IE 10 não tem suporte para Web Workers compartilhados , portanto, também não é relevante. Resta o Chrome.

Aqui está um exemplo para testar web workers compartilhados.

Primeiro o 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>

Em seguida, a implementação do próprio trabalhador compartilhado em 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 do teste no Chrome 20 ( a resposta ):

Quando a página é carregada simultaneamente em duas guias separadas, a contagem de conexões aumenta cada vez que uma das páginas é recarregada ou o link autorreferencial é clicado.

Se apenas uma única instância da página for carregada, a contagem de conexões nunca será alterada quando a página for recarregada ou o link for clicado.

Portanto, no Chrome 20: Web Workers compartilhados não persistem em recarregamentos de página e cliques de navegação em link .

Outras dicas

Parece que este é basicamente o mesmo problema que a questão 'O que acontece com um thread de trabalho da web HTML5 quando a guia é fechada durante a execução?' . Acho que a parte principal da especificação é esta declaração :

Os agentes do usuário podem invocar o modelo de processamento "matar um trabalhador" em um trabalhador a qualquer momento, por exemplo, em resposta às solicitações do usuário, em resposta a Gerenciamento de cota de CPU ou quando um trabalhador deixa de ser um ativo necessário trabalhador se o trabalhador continuar executando mesmo após seu sinalizador de fechamento foi definido como verdadeiro.

Um ' ativo trabalhador necessário 'é definido da seguinte forma:

Um trabalhador é considerado um trabalhador ativo necessário se qualquer um dos documentos os objetos nos Documentos do trabalhador estão totalmente ativos.

Portanto, pelo que entendi, se todas as janelas que fazem referência a um trabalhador forem fechadas, o navegador é obrigado pela especificação a encerrar o trabalhador, mas não imediatamente. Dependendo dele, a persistência não será confiável, mesmo que pareça funcionar ocasionalmente.

Em seu exemplo, minha abordagem seria carregar todo o site por Ajax - você não conseguirá executar os Web Workers se seus usuários desativaram o JS de qualquer maneira, então use o API de histórico para fazer com que o endereço da página do usuário corresponda a a página real (mantendo o mecanismo de pesquisa e a compatibilidade não JS).

Tive sucesso com uma técnica meio indireta em que, quando quero ir para a próxima página, mas mantenho o SharedWorker, abro uma janela pop-up (esperançosamente discreta) que cria o mesmo trabalhador, espero que ele se torne ativo eenvia uma mensagem para a porta / janela original, que então navega para a nova página e, quando a página é carregada, fecha o pop-up.Essa estratégia mantém pelo menos uma conexão ativa o tempo todo, para que o trabalhador nunca decida desligar.

Esta técnica parece ser bastante robusta até agora.Embora ver o pop-up seja um tanto chato, é um meio-termo razoável para alguns casos de uso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top