Meu Entendimento sobre Pesquisa HTTP, Pesquisa Longa, Streaming HTTP e WebSockets


123

Eu li muitos posts no SO e na web sobre as palavras-chave no título da minha pergunta e aprendi muito com elas. Algumas das perguntas que li estão relacionadas a desafios específicos de implementação, enquanto outras se concentram em conceitos gerais. Eu só quero ter certeza de que entendi todos os conceitos e o motivo pelo qual a tecnologia X foi inventada sobre a tecnologia Y e assim por diante. Então aqui vai:

Pesquisa de HTTP: Basicamente AJAX, usando XmlHttpRequest.

Pesquisa longa por HTTP: AJAX, mas o servidor mantém a resposta, a menos que o servidor tenha uma atualização, assim que o servidor tiver uma atualização, ele a envia e o cliente pode enviar outra solicitação. Desvantagem são os dados adicionais do cabeçalho que precisam ser enviados para frente e para trás, causando sobrecarga adicional.

Streaming de HTTP: semelhante à pesquisa longa, mas o servidor responde com um cabeçalho com "Transfer Encoding: chunked" e, portanto, não precisamos iniciar uma nova solicitação toda vez que o servidor envia alguns dados (e, portanto, salva a sobrecarga adicional do cabeçalho). A desvantagem aqui é que precisamos "entender" e descobrir a estrutura dos dados para distinguir entre vários pedaços enviados pelo servidor.

Applet Java, Flash, Silverlight: Eles fornecem a capacidade de conectar-se a servidores de soquete por tcp / ip, mas como são plugins, os desenvolvedores não querem depender deles.

WebSockets: são a nova API que tenta abordar as falhas dos métodos acima da seguinte maneira:

  • A única vantagem do WebSockets em relação a plug-ins como Java Applets, Flash ou Silverlight é que o WebSockets é nativamente incorporado aos navegadores e não depende de plug-ins.
  • A única vantagem do WebSockets sobre o streaming http é que você não precisa se esforçar para "entender" e analisar os dados recebidos.
  • A única vantagem do WebSockets sobre a pesquisa longa é a eliminação do tamanho extra dos cabeçalhos, a abertura e o fechamento da conexão do soquete, mediante solicitação.

Faltam outras diferenças significativas? Sinto muito se estou re-perguntando ou combinando muitas das perguntas que já estão no SO em uma única pergunta, mas só quero fazer todo o sentido de todas as informações disponíveis no SO e na Web sobre esses conceitos.

Obrigado!


4
Eventos enviados pelo servidor também podem ser vistos quando você não precisa de comunicação bidirecional.
Leggetter

1
Esta é uma pergunta realmente útil. Eu acho que seria potencialmente mais útil se houvesse uma resposta para a qual vários autores pudessem contribuir.
Leggetter

Obrigado, Phil, obrigado pela dica sobre os eventos enviados pelo servidor. Estou interessado em aprender sobre os cenários de comunicação bidirecional. obrigado.
Software Guy

1
Com o HTTP Streaming e o Long-Polling, você precisa de uma segunda conexão para comunicação bidirecional. Uma conexão de maior duração para a comunicação servidor -> cliente 'push' e uma segunda conexão de curta duração para as comunicações cliente -> servidor. Essa segunda conexão é usada para fazer coisas como configurar e alterar assinaturas de dados. Portanto, o EventSource pode ser usado em uma solução bidirecional e, na verdade, é uma solução padronizada nascida de HTTP Streaming e Long-Polling.
Leggetter

1
Você também pode querer verificar para fora esta classificação de técnicas escrevi: stackoverflow.com/questions/12078550/...
Alessandro Alinone

Respostas:


92

Existem mais diferenças do que as que você identificou.

Duplex / direcional:

  • Unidirecional: pesquisa HTTP, pesquisa longa, streaming.
  • Bidirecional: WebSockets, rede de plugins

Em ordem crescente de latência (aproximada):

  • WebSockets
  • Rede de plug-ins
  • Transmissão HTTP
  • Pesquisa longa HTTP
  • Sondagem HTTP

CORS (suporte de origem):

  • WebSockets: sim
  • Rede de plug-ins: Flash via solicitação de política (não tenho certeza sobre outras pessoas)
  • HTTP * (algum suporte recente)

Dados binários nativos (matrizes digitadas, blobs):

  • WebSockets: sim
  • Rede de plug-ins: não com Flash (requer codificação de URL em ExternalInterface)
  • HTTP *: proposta recente para ativar o suporte ao tipo binário

Largura de banda na diminuição da eficiência:

  • Rede de plug-ins: soquetes Flash não processados, exceto para solicitação de política inicial
  • WebSockets: handshake de configuração de conexão e alguns bytes por quadro
  • Streaming HTTP (reutilização da conexão do servidor)
  • Pesquisa longa HTTP: conexão para cada mensagem
  • Pesquisa HTTP: conexão para cada mensagem + sem mensagens de dados

Suporte para dispositivo móvel:

  • WebSocket: iOS 4.2 e superior. Alguns Android via emulação Flash ou usando o Firefox para Android ou o Google Chrome para Android, ambos oferecem suporte nativo ao WebSocket.
  • Rede de plug-ins: alguns Android. Não no iOS
  • HTTP *: principalmente sim

Complexidade de uso de Javascript (do mais simples ao mais complicado). É certo que as medidas de complexidade são um tanto subjetivas.

  • WebSockets
  • Sondagem HTTP
  • Rede de plug-ins
  • Enquete HTTP longa, streaming

Observe também que há uma proposta do W3C para padronizar o fluxo HTTP chamado Eventos enviados pelo servidor . Atualmente, está bastante adiantado em sua evolução e foi projetado para fornecer uma API Javascript padrão com simplicidade comparável ao WebSockets.


1
Muito obrigado pela boa resposta Kanaka. Você pode me dizer por que / como o streaming http tem uma latência mais alta que os websockets? talvez com um exemplo simples? Muito obrigado.
Software Guy

2
@SoftwareGuy. Muitas razões. Em navegadores recentes, você pode usar o manipulador de eventos XMLHTTPRequest onprogress para ser notificado dos dados. Mas a especificação diz que 50ms é o menor intervalo de notificação. Caso contrário, você deve pesquisar dados de resposta. Além disso, os envios do cliente estabelecem uma nova conexão HTTP e aumentam significativamente a latência de ida e volta. Além disso, muitos servidores da Web cortam as conexões HTTP após 30 segundos ou mais, o que significa que você frequentemente precisa restabelecer a conexão por push do servidor. Vi latências de ida e volta do WebSocket de 5 a 10 ms em uma rede local. A latência do streaming HTTP provavelmente seria 50ms +.
Kanaka

Muito obrigado pela resposta detalhada :)
Software Guy

1
@leggetter Obrigado Phil, você quer dizer que enviar dados do cliente para o servidor via fluxo de http causará sobrecarga? é possível enviar dados para o servidor via streaming http sem abrir uma nova conexão? Obrigado.
Software Guy

1
@ Nathan parece um bom projeto de tese de mestrado! Certamente, as pesquisas manterão o sistema mais ocupado do que um modelo orientado a eventos, mas o que exatamente pode ser a economia de energia exigiria testes empíricos bastante extensos em diferentes escalas.
Kanaka #

13

Algumas ótimas respostas de outras pessoas que cobrem muito terreno. Aqui está um pouco mais.

A única vantagem do WebSockets em relação a plug-ins como Java Applets, Flash ou Silverlight é que o WebSockets é nativamente incorporado aos navegadores e não depende de plug-ins.

Se com isso você quer dizer que pode usar Java Applets, Flash ou Silverlight para estabelecer uma conexão de soquete, então sim, isso é possível. No entanto, você não vê isso implantado no mundo real com muita frequência por causa das restrições.

Por exemplo, os intermediários podem e encerram esse tráfego. O padrão WebSocket foi projetado para ser compatível com a infraestrutura HTTP existente e, portanto, é muito menos suscetível a interferências de intermediários, como firewalls e proxies.

Além disso, o WebSocket pode usar as portas 80 e 443 sem a necessidade de portas dedicadas, novamente graças ao design do protocolo para ser o mais compatível possível com a infraestrutura HTTP existente.

Essas alternativas de soquete (Java, Flash e Silverlight) são difíceis de usar com segurança em uma arquitetura de origem cruzada. Assim, as pessoas que tentam usá-las com origem cruzada toleram as inseguranças em vez de se esforçarem para fazê-lo com segurança.

Eles também podem exigir a abertura de portas "não padronizadas" adicionais (algo que os administradores detestam fazer) ou arquivos de políticas que precisam ser gerenciados.

Em resumo, o uso de Java, Flash ou Silverlight para conectividade de soquete é problemático o suficiente para que você não o veja implantado em arquiteturas sérias com muita frequência. Flash e Java têm esse recurso há provavelmente pelo menos 10 anos, e ainda assim não é predominante.

O padrão WebSocket foi capaz de começar com uma nova abordagem, tendo em mente essas restrições e, esperançosamente, tendo aprendido algumas lições com elas.

Algumas implementações do WebSocket usam Flash (ou possivelmente Silverlight e / ou Java) como substituto quando a conectividade do WebSocket não pode ser estabelecida (como ao executar em um navegador antigo ou quando um intermediário interfere).

Embora algum tipo de estratégia de fallback para essas situações seja inteligente, mesmo necessário, a maioria das pessoas que usam Flash et al sofrerá com as desvantagens descritas acima. Não precisa ser assim - existem soluções alternativas para obter conexões seguras com origem cruzada usando Flash, Silverlight, etc. - mas a maioria das implementações não faz isso porque não é fácil.

Por exemplo, se você confiar no WebSocket para uma conexão de origem cruzada, isso funcionará bem. Mas se você executar em um navegador antigo ou um firewall / proxy interferir e confiar no Flash, por exemplo, como seu substituto, será difícil fazer a mesma conexão de origem cruzada. A menos que você não se importe com segurança, é claro.

Isso significa que é difícil ter uma arquitetura unificada única que funcione para conexões nativas e não nativas, a menos que você esteja preparado para trabalhar bastante ou seguir uma estrutura que tenha feito isso bem. Em uma arquitetura ideal, você não notaria se as conexões eram nativas ou não; suas configurações de segurança funcionariam nos dois casos; suas configurações de cluster ainda funcionariam; seu planejamento de capacidade ainda seria válido; e assim por diante.

A única vantagem do WebSockets sobre o streaming http é que você não precisa se esforçar para "entender" e analisar os dados recebidos.

Não é tão simples quanto abrir um fluxo HTTP e relaxar, pois seus dados fluem por minutos, horas ou mais. Diferentes clientes se comportam de maneira diferente e você precisa gerenciar isso. Por exemplo, alguns clientes armazenam em buffer os dados e não os liberam no aplicativo até que algum limite seja atingido. Pior ainda, alguns não passarão os dados para o aplicativo até que a conexão seja fechada.

Portanto, se você estiver enviando várias mensagens para o cliente, é possível que o aplicativo cliente não receba os dados até que 50 mensagens de dados sejam recebidas, por exemplo. Isso não é muito em tempo real.

Embora o streaming HTTP possa ser uma alternativa viável quando o WebSocket não estiver disponível, não é uma panacéia. Ele precisa de um bom entendimento para funcionar de maneira robusta nas áreas remotas da Web em condições reais.

Faltam outras diferenças significativas?

Há mais uma coisa que ninguém mencionou ainda, então vou falar disso.

O protocolo WebSocket foi projetado para ser uma camada de transporte para protocolos de nível superior. Embora você possa enviar mensagens JSON ou o que não é diretamente por uma conexão WebSocket, ele também pode transportar protocolos padrão ou personalizados.

Por exemplo, você pode fazer AMQP ou XMPP sobre WebSocket, como as pessoas já fizeram. Portanto, um cliente pode receber mensagens de um broker AMQP como se estivesse conectado diretamente ao próprio broker (e, em alguns casos, é).

Ou, se você já possui um servidor com algum protocolo personalizado, pode transportá-lo pelo WebSocket, estendendo esse servidor de back-end para a Web. Geralmente, um aplicativo existente bloqueado na empresa pode ampliar seu alcance usando o WebSocket, sem precisar alterar nenhuma infraestrutura de back-end.

(Naturalmente, você poderá fazer tudo isso de forma segura, portanto verifique com o fornecedor ou o provedor WebSocket.)

Algumas pessoas se referiram ao WebSocket como TCP para a Web. Como o TCP transporta protocolos de nível superior, o mesmo ocorre com o WebSocket, mas de uma maneira compatível com a infraestrutura da Web.

Portanto, embora o envio de mensagens JSON (ou o que seja) diretamente pelo WebSocket seja sempre possível, é preciso considerar também os protocolos existentes. Porque para muitas coisas que você deseja fazer, provavelmente existe um protocolo que já foi pensado para isso.

Sinto muito se estou re-perguntando ou combinando muitas das perguntas que já estão no SO em uma única pergunta, mas só quero fazer todo o sentido de todas as informações disponíveis no SO e na Web sobre esses conceitos.

Esta foi uma ótima pergunta, e as respostas foram todas muito informativas!


Muito obrigado Robin pela excelente ajuda e informações. Se eu puder perguntar uma coisa adicional: me deparei com um artigo em algum lugar que diz que o streaming http também pode ser armazenado em cache por proxies enquanto os websockets não o são. o que isso significa?
Software Guy

Porque StackOverflow limita o tamanho nos comentários de resposta, eu dei minha resposta abaixo: stackoverflow.com/questions/12555043/...
Robin Zimmermann

@RobinZimmermann, sua resposta é minha favorita. +1 para obter uma resposta detalhada realmente boa.
securecurve

10

Se eu puder perguntar uma coisa adicional: me deparei com um artigo em algum lugar que diz que o streaming http também pode ser armazenado em cache por proxies enquanto os websockets não o são. o que isso significa?

(StackOverflow limita o tamanho das respostas dos comentários, por isso tive que responder aqui em vez de incorporar.)

Este é um bom ponto. Para entender isso, pense em um cenário HTTP tradicional ... Imagine que um navegador abriu uma página da Web e solicita http://example.com , digamos. O servidor responde com HTTP que contém o HTML da página. Em seguida, o navegador vê que existem recursos na página e, portanto, começa a solicitar os arquivos CSS, JavaScript e imagens. Todos eles são arquivos estáticos que serão iguais para todos os clientes que os solicitarem.

Alguns proxies armazenam em cache recursos estáticos para que solicitações subsequentes de outros clientes possam obter esses recursos estáticos do proxy, em vez de precisar voltar ao servidor da Web central para obtê-los. Isso é cache e é uma ótima estratégia para descarregar solicitações e processamento de seus serviços centrais.

Então, o cliente nº 1 solicita http://example.com/images/logo.gif , digamos. Essa solicitação passa pelo proxy até o servidor da web central, que serve logo.gif. À medida que o logo.gif passa pelo proxy, o proxy salva a imagem e a associa ao endereço http://example.com/images/logo.gif .

Quando o cliente nº 2 aparece e também solicita http://example.com/images/logo.gif , o proxy pode retornar a imagem e nenhuma comunicação é necessária de volta ao servidor da web no centro. Isso fornece uma resposta mais rápida ao usuário final, o que é sempre ótimo, mas também significa que há menos carga no centro. Isso pode se traduzir em custos reduzidos de hardware, custos reduzidos de rede, etc. Portanto, é uma coisa boa.

O problema surge quando o logo.gif é atualizado no servidor da web. O proxy continuará a exibir a imagem antiga, sem saber que há uma nova imagem. Isso leva a um processo completo de expiração, para que o proxy armazene em cache a imagem apenas por um curto período de tempo antes de "expirar" e a próxima solicitação passará pelo proxy para o servidor da web, que atualiza o cache do proxy. Também existem soluções mais avançadas nas quais um servidor central pode enviar para caches conhecidos e assim por diante, e as coisas podem ficar bem sofisticadas.

Como isso se encaixa na sua pergunta?

Você perguntou sobre o streaming HTTP em que o servidor está transmitindo HTTP para um cliente. Mas o streaming de HTTP é como o HTTP comum, exceto que você não para de enviar dados. Se um servidor da web exibir uma imagem, ele envia HTTP ao cliente que eventualmente termina: você enviou a imagem inteira. E se você deseja enviar dados, é exatamente o mesmo, mas o servidor apenas envia por um longo tempo (como se fosse uma imagem gigantesca, digamos) ou mesmo nunca termina.

Do ponto de vista do proxy, ele não pode distinguir entre HTTP para um recurso estático, como uma imagem, ou dados do fluxo HTTP. Nos dois casos, o cliente fez uma solicitação ao servidor. O proxy lembrou a solicitação e também a resposta. Na próxima vez em que a solicitação for recebida, o proxy atenderá a mesma resposta.

Portanto, se o seu cliente fez uma solicitação de preço das ações, digamos, e obteve uma resposta, o próximo cliente pode fazer a mesma solicitação e obter os dados em cache. Provavelmente não é o que você quer! Se você solicitar preços das ações, deseja os dados mais recentes, certo?

Então é um problema.

Existem truques e soluções alternativas para lidar com problemas como esse, é verdade. Obviamente, você pode fazer com que o streaming HTTP funcione, pois é usado atualmente. É tudo transparente para o usuário final, mas as pessoas que desenvolvem e mantêm essas arquiteturas precisam passar por obstáculos e pagar um preço. Isso resulta em arquiteturas complicadas demais, o que significa mais manutenção, mais hardware, mais complexidade, mais custo. Isso também significa que os desenvolvedores geralmente precisam se preocupar com algo que não deveriam, quando deveriam se concentrar apenas no aplicativo, na GUI e na lógica de negócios - eles não deveriam se preocupar com a comunicação subjacente.


1
excelente detalhe Robin, muito obrigado! Eu realmente aprecio sua resposta completa. Eu já aprendi muito com todas as grandes pessoas aqui! :)
Software Guy

4

O HTTP limita o número de conexões que um cliente pode ter com um servidor para 2 (embora isso possa ser atenuado usando subdomínios) e o IE é conhecido por impor isso ansiosamente. O Firefox e o Chrome permitem mais (embora não me lembre exatamente do topo da minha cabeça). Isso pode não parecer um grande problema, mas se você estiver usando 1 conexão constantemente para atualizações em tempo real, todas as outras solicitações deverão ter gargalo na outra conexão HTTP. E existe a questão de ter mais conexões abertas dos clientes, colocando mais carga no servidor.

Os WebSockets são um protocolo baseado em TCP e, como tal, não sofrem com esse limite de conexão no nível HTTP (mas, é claro, o suporte ao navegador não é uniforme).


obrigado thejuice, portanto, além do problema de várias conexões simultâneas, conforme destacado por você, o restante das minhas suposições sobre os websockets está correto?
Software Guy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.