Atualmente, estou trabalhando em um projeto Ruby on Rails que mostra uma lista de imagens.
Um item essencial para esse projeto é que ele mostra novas postagens em tempo real sem a necessidade de atualizar a página da web. Depois de pesquisar um pouco, deparei-me com algumas soluções e serviços JavaScript, como o PubNub; no entanto, nenhuma das soluções fornecidas fazia sentido.
Na solução JavaScript ( sondagem ), acontece o seguinte:
- O usuário 1 visualiza a lista de fotos.
- Em segundo plano, o código JavaScript está pesquisando um ponto de extremidade a cada segundo para ver se há uma nova postagem.
- O usuário 2 adiciona uma nova foto.
- Há um atraso de 50 ms antes que o novo ciclo seja acionado e busque os novos dados.
- O novo conteúdo é carregado no DOM .
Isso parece estranho quando traduzido para um exemplo do mundo real:
- O usuário 1 tem uma pilha de fotos em sua mesa.
- Ele / ela caminha para o fotógrafo a cada segundo e pergunta se ele tem um novo.
- O fotógrafo faz uma nova foto.
- Neste segundo, quando ele entra, pode tirar a foto e colocá-la na pilha.
Na minha opinião, a solução deve ser a seguinte:
- O usuário 1 tem uma pilha de fotos em sua mesa.
- O fotógrafo tira uma nova foto.
- O fotógrafo caminha até a pilha e a põe com o resto.
A solução PubNub é basicamente a mesma, porém desta vez há um estagiário caminhando entre as partes para compartilhar os dados.
Desnecessário dizer que ambas as soluções consomem muita energia, pois são acionadas mesmo quando não há dados para carregar.
No que diz respeito ao meu conhecimento, não há explicação (lógica) por que esse modo de implementação é usado em quase todos os aplicativos em tempo real.
Respostas:
O envio funciona bem para 1 ou para um número limitado de usuários.
Agora mude o cenário com um fotógrafo e 1.000 usuários que desejam uma cópia da imagem. O fotógrafo terá que caminhar até 1000 pilhas. Alguns deles podem estar no escritório trancado ou espalhados por todo o chão. Ou o usuário em férias e não está interessado em novas fotos no momento.
O fotógrafo ficaria ocupado andando o tempo todo e não tiraria novas fotos.
Fundamentalmente: um modelo de pull / poll dimensiona melhor para muitos leitores não confiáveis, com requisitos em tempo real frouxos (se uma imagem leva 10 segundos depois para chegar à pilha, qual é o problema)?
Dito isto, um modelo push ainda é melhor em muitas situações. Se você precisar de baixa latência (precisa da nova foto 5s depois de tirada), ou as atualizações forem raras e solicite freqüentes e previsíveis (pergunte ao fotógrafo a cada 10 segundos quando ele gerar uma nova foto por dia), puxar é inapropriado. Depende do que você está tentando fazer. NASDAQ: push. Serviço meteorológico: tração. Fotógrafo de casamento: provavelmente pull. Agência de notícias: provavelmente pressione.
fonte
Estou realmente surpreso que apenas uma pessoa tenha mencionado os WebSockets . O suporte é implementado em basicamente todos os principais navegadores .
De fato, o PubNub os usa. Para seu aplicativo, o navegador provavelmente assinaria um soquete que seria transmitido sempre que uma nova foto estivesse disponível. O soquete não envia a foto, lembre-se, mas apenas um link para que o navegador possa baixá-la de forma assíncrona.
No seu exemplo, imagine algo como:
É um pouco como a sua solução de exemplo original. É mais eficiente do que a pesquisa porque o cliente não precisa enviar nenhum dado ao servidor (exceto, talvez, batimentos cardíacos ).
Além disso, como outros já mencionaram, existem outros métodos que são melhores do que simples pesquisas que funcionam em navegadores mais antigos ( longpolling, et al .)
fonte
StackExchange
sites como o que você está usando agora (a menos que esteja vendo esta página em cache / salva) usamWebSockets
. Era por isso que eu também estava me perguntando por que ninguém até @korylprince mencionouWebSockets
.Às vezes, bom o suficiente é bom o suficiente.
De todas as formas possíveis de implementar um processo de comunicação em "tempo real", a pesquisa talvez seja a maneira mais simples. A pesquisa pode ser usada efetivamente quando o intervalo de pesquisa é relativamente longo (ou seja, segundos, minutos ou horas, e não instantâneo), e o ciclo do relógio consumido verificando a conexão ou o recurso realmente não importa.
fonte
O protocolo HTTP é limitado, pois o cliente DEVE ser o único a iniciar a solicitação. O servidor não pode se comunicar com o cliente, a menos que responda a uma solicitação do cliente.
Portanto, para ajustar seu exemplo do mundo real, adicione a seguinte restrição:
Com essa nova restrição, como você faria isso além da votação?
fonte
Por que a pesquisa é aceita? Porque, na realidade, todas as soluções são realmente pesquisas de baixo nível!
Se o servidor precisar atualizá-lo assim que novas fotos estiverem disponíveis, ele geralmente precisará ter uma conexão com você - porque os endereços IP mudam frequentemente e você nunca sabe se alguém não está mais interessado, portanto, o cliente precisa enviar algum tipo de sinal keep-alive, por exemplo, "ainda estou aqui, não estou offline"
Todas as conexões com estado (por exemplo, TCP / IP) funcionam da mesma maneira, pois você só pode enviar pacotes de dados únicos pela Internet; você nunca sabe se a outra parte ainda está lá.
Portanto, todo protocolo tem um tempo limite. Se uma entidade não responder dentro de X segundos, presume-se que ela esteja morta. Portanto, mesmo que você tenha apenas uma conexão aberta entre servidor e cliente, sem enviar nenhum dado, o servidor e o cliente precisam enviar pacotes keep-alive regulares (isso é tratado de baixo nível se você abrir uma conexão entre eles) - e como é isso no final é diferente de pesquisa?
Portanto, a melhor abordagem provavelmente seria longa:
O cliente envia uma solicitação imediatamente após o carregamento do site (por exemplo, dizendo ao fotógrafo "Diga-me se há novas fotos"), mas o servidor não responde se não houver novas fotos. Assim que a solicitação expira, o cliente pergunta novamente.
Se o servidor agora tiver novas fotos, ele poderá responder imediatamente a todos os clientes que estão na fila para novas fotos. Portanto, seu tempo de reação após uma nova imagem é ainda menor do que com o envio por push, pois o cliente ainda aguarda uma resposta em uma conexão aberta e você não precisa criar uma conexão com o cliente. E as solicitações de pesquisa do cliente não são muito mais tráfego do que uma conexão constante entre cliente e servidor para uma resposta!
fonte
Uma vantagem da pesquisa é que ela limita o dano que pode ser causado se uma mensagem desaparecer ou se o estado de algo for danificado. Se X solicitar seu estado a Y uma vez a cada cinco segundos, a perda de uma solicitação ou resposta resultará apenas na informação de X sendo dez segundos desatualizada em vez de 5. Se Y for reiniciado, X poderá descobrir sobre isso na próxima o tempo Y é capaz de responder a uma das mensagens de X. Se o X for reiniciado, talvez nunca mais lhe peça nada, mas quem estiver observando o status do X deve reconhecer que foi reiniciado.
Se, em vez de X pesquisar Y, X confiasse em Y para informá-lo sempre que seu estado fosse alterado, se o estado de Y mudasse e ele enviasse uma mensagem para X, mas por qualquer motivo, essa mensagem não foi recebida, X poderá nunca tomar conhecimento da alteração . Da mesma forma, se Y for reiniciado e nunca tiver qualquer motivo para enviar uma mensagem a X sobre algo.
Em alguns casos, pode ser útil para o X solicitar que Y envie autonomamente mensagens com seu status, periodicamente ou quando elas forem alteradas, e só faça a pesquisa X se demorar demais sem ouvir nada de Y. Esse design pode eliminar o é necessário que X envie a maioria de suas mensagens (normalmente, X deve ao menos ocasionalmente informar Y de que ainda está interessado em receber mensagens e Y deve parar de enviar mensagens se demorar demais sem qualquer indicação de interesse). Tal projeto exigiria, no entanto, que Y persistissemantenha as informações sobre o X, em vez de poder simplesmente enviar uma resposta para quem as pesquisou e depois esquecer imediatamente quem era. Se Y for um sistema incorporado, essa simplificação pode ajudar a reduzir os requisitos de memória o suficiente para permitir o uso de um controlador menor e mais barato.
A pesquisa pode ter uma vantagem adicional ao usar um meio de comunicação potencialmente não confiável (por exemplo, UDP ou rádio): ele elimina amplamente a necessidade de reconhecimento da camada de link. Se X enviar a Y uma solicitação de status Q, Y responder com um relatório de status R e X ouvir R, X não precisará ouvir nenhum tipo de reconhecimento da camada de link para que Q saiba que foi recebido. Por outro lado, uma vez que Y envia R, ele não precisa saber ou se importar se X o recebeu. Se X envia uma solicitação de status e não obtém resposta, ele pode enviar outra. Se Y enviar um relatório e X não o ouvir, X enviará outra solicitação. Se cada solicitação sair uma vez e fornecer uma resposta ou não, nenhuma das partes precisará saber ou se importar se alguma mensagem específica foi recebida. Como o envio de uma confirmação pode consumir quase a mesma largura de banda que uma solicitação ou relatório de status, o uso de uma viagem de ida e volta de relatório de solicitação não custa muito mais do que custaria um relatório e uma confirmação não solicitados. Se o X enviar algumas solicitações sem obter respostas, em algumas redes roteadas dinamicamente, será necessário habilitar as confirmações no nível do link (e solicitar na solicitação que Y faça o mesmo) para que a pilha de protocolos subjacente possa reconhecer o problema de entrega e procurar por uma nova rota, mas quando as coisas estiverem funcionando, um modelo de relatório de solicitação será mais eficiente do que usar confirmações no nível do link.
fonte
A questão é equilibrar a quantidade de pesquisas desnecessárias versus a quantidade de empurrões desnecessários.
Se você pesquisar:
Se você pressionar:
Existem várias soluções sobre como lidar com os vários cenários e suas desvantagens, como, por exemplo, um tempo mínimo entre pesquisas, proxies somente de pesquisas para retirar a carga do sistema principal ou - para os empurrões - um regulamento para registrar e especificar os dados desejados seguidos pelo cancelamento do registro no logoff. Qual deles se encaixa melhor não é nada que você possa dizer em geral, depende do sistema.
No seu exemplo, a pesquisa não é a solução mais eficiente, mas a mais prática. É muito fácil escrever um sistema de votação em JavaScript e também muito fácil implementá-lo no lado da entrega. Um servidor criado para fornecer dados de imagem deve ser capaz de lidar com solicitações extras e, se não, pode ser dimensionado linearmente, pois os dados geralmente são estáticos e, portanto, podem ser facilmente armazenados em cache.
Um método push implementando um logon, descrição dos dados desejados e, finalmente, um logoff seria mais eficiente, mas provavelmente é muito complexo para o "script-kiddy" médio e precisa lidar com a pergunta: e se o usuário apenas desliga o navegador e o logoff não pode ser realizado?
Talvez seja melhor ter mais usuários (o acesso é fácil) do que economizar algum dinheiro em outro servidor de cache?
fonte
Por alguma razão, hoje em dia, todos os desenvolvedores da Web mais jovens parecem ter esquecido as lições do passado, e por que algumas coisas evoluíram da maneira que fizeram.
Diante dessas restrições, talvez você não tenha uma comunicação bidirecional constante. E se você analisasse o modelo OSI, descobriria que a maioria das considerações visa dissociar a persistência com a conexão subjacente.
Com isso em mente, um método de pesquisa de informações é uma ótima maneira de reduzir a largura de banda e a computação no lado do cliente. O aumento da pressão é, na maioria das vezes, apenas o cliente que realiza pesquisas constantes ou soquetes da web. Pessoalmente, se eu fosse todo mundo lá fora, eu apreciaria a regularidade da pesquisa como um meio de análise de tráfego, onde uma solicitação GET / POST fora do tempo sinalizaria um homem na situação intermediária de algum tipo.
fonte