Protocolo WebSockets vs HTTP

330

Existem muitos blogs e discussões sobre websocket e HTTP, e muitos desenvolvedores e sites defendem fortemente os websockets, mas ainda não consigo entender o porquê.

por exemplo (argumentos de amantes de websocket):

Os soquetes da Web em HTML5 representam a próxima evolução das comunicações na Web - um canal de comunicação bidirecional full-duplex que opera através de um único soquete na Web. ( http://www.websocket.org/quantum.html )

O HTTP oferece suporte ao streaming: solicite o streaming do corpo (você o está usando durante o upload de arquivos grandes) e o streaming do corpo da resposta.

Durante a conexão com o WebSocket, o cliente e o servidor trocam dados por quadro, com 2 bytes cada, em comparação com 8 kg de bytes do cabeçalho http quando você faz pesquisa contínua.

Por que esses 2 bytes não incluem os protocolos TCP e TCP?

GET /about.html HTTP/1.1
Host: example.org

Este é o cabeçalho http de ~ 48 bytes.

codificação em pedaços http - https://en.wikipedia.org/wiki/Chunked_transfer_encoding :

23
This is the data in the first chunk
1A
and this is the second one
3
con
8
sequence
0
  • Portanto, a sobrecarga por cada pedaço não é grande.

Os dois protocolos também funcionam com TCP, portanto todos os problemas de TCP com conexões de longa duração ainda estão lá.

Questões:

  1. Por que o protocolo websockets é melhor?
  2. Por que foi implementado em vez de atualizar o protocolo http?
4esn0k
fonte
2
Qual a sua pergunta?
Jonas
@Jonas, 1) por que o protocolo websockets é melhor? 2) Por que foi implementado em vez de atualizar o protocolo http? 3) Por que os websockets são tão promovidos?
precisa saber é o seguinte
@JoachimPileborg, você pode fazer isso com soquetes TCP ou http também para aplicativos de desktop; e você tem que usar WebRTC para tornar a comunicação navegador-to-browser para o site
4esn0k
@JoachimPileborg, é WebRTC para o navegador-to-browser, não WebSockets
4esn0k
@ 4esn0k, o WS não é melhor, eles são diferentes e melhores para algumas tarefas específicas. 3) É um novo recurso que as pessoas devem conhecer e abrir novas possibilidades para a Web
Jonas

Respostas:

491

1) Por que o protocolo WebSockets é melhor?

O WebSockets é melhor para situações que envolvem comunicação de baixa latência, especialmente para baixa latência para mensagens de cliente para servidor. Para dados de servidor para cliente, é possível obter uma latência bastante baixa usando conexões de longa data e transferência em blocos. No entanto, isso não ajuda na latência do cliente para o servidor, o que requer que uma nova conexão seja estabelecida para cada mensagem de cliente para servidor.

Seu handshake HTTP de 48 bytes não é realista para conexões do navegador HTTP do mundo real, onde geralmente existem vários kilobytes de dados enviados como parte da solicitação (em ambas as direções), incluindo muitos dados de cabeçalhos e cookies. Aqui está um exemplo de uma solicitação / resposta para usar o Chrome:

Solicitação de exemplo (2800 bytes, incluindo dados do cookie, 490 bytes sem dados do cookie):

GET / HTTP/1.1
Host: www.cnn.com
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.68 Safari/537.17
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: [[[2428 byte of cookie data]]]

Resposta de exemplo (355 bytes):

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 13 Feb 2013 18:56:27 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: CG=US:TX:Arlington; path=/
Last-Modified: Wed, 13 Feb 2013 18:55:22 GMT
Vary: Accept-Encoding
Cache-Control: max-age=60, private
Expires: Wed, 13 Feb 2013 18:56:54 GMT
Content-Encoding: gzip

HTTP e WebSockets têm handshakes de conexão inicial de tamanho equivalente, mas com uma conexão WebSocket o handshake inicial é executado uma vez e, em seguida, pequenas mensagens possuem apenas 6 bytes de sobrecarga (2 para o cabeçalho e 4 para o valor da máscara). A sobrecarga de latência não é muito do tamanho dos cabeçalhos, mas da lógica para analisar / manipular / armazenar esses cabeçalhos. Além disso, a latência da configuração da conexão TCP provavelmente é um fator maior que o tamanho ou o tempo de processamento de cada solicitação.

2) Por que foi implementado em vez de atualizar o protocolo HTTP?

Há esforços para reprojetar o protocolo HTTP para obter melhor desempenho e menor latência, como SPDY , HTTP 2.0 e QUIC . Isso melhorará a situação das solicitações HTTP normais, mas é provável que o WebSockets e / ou o WebRTC DataChannel ainda tenham menor latência para transferência de dados de cliente para servidor do que o protocolo HTTP (ou será usado em um modo semelhante ao WebSockets enfim).

Atualização :

Aqui está uma estrutura para pensar em protocolos da web:

  • TCP : camada de transporte de pedidos de baixo nível, bidirecional, full-duplex e garantida. Não há suporte para navegador (exceto via plugin / Flash).
  • HTTP 1.0 : protocolo de transporte solicitação-resposta em camadas no TCP. O cliente faz uma solicitação completa, o servidor fornece uma resposta completa e a conexão é fechada. Os métodos de solicitação (GET, POST, HEAD) têm significado transacional específico para recursos no servidor.
  • HTTP 1.1 : mantém a natureza de solicitação-resposta do HTTP 1.0, mas permite que a conexão permaneça aberta para várias solicitações / respostas completas (uma resposta por solicitação). Ainda possui cabeçalhos completos na solicitação e resposta, mas a conexão é reutilizada e não fechada. O HTTP 1.1 também adicionou alguns métodos de solicitação adicionais (OPTIONS, PUT, DELETE, TRACE, CONNECT) que também possuem significados transacionais específicos. No entanto, conforme observado na introdução à proposta de rascunho do HTTP 2.0, o pipelining do HTTP 1.1 não é amplamente implantado; portanto, isso limita muito o utilitário do HTTP 1.1 para resolver a latência entre navegadores e servidores.
  • Pesquisa longa : tipo de "hack" para HTTP (1.0 ou 1.1) em que o servidor não responde imediatamente (ou apenas parcialmente com cabeçalhos) à solicitação do cliente. Após uma resposta do servidor, o cliente envia imediatamente uma nova solicitação (usando a mesma conexão se for através do HTTP 1.1).
  • Streaming HTTP : uma variedade de técnicas (resposta em várias partes / partes) que permitem ao servidor enviar mais de uma resposta para uma única solicitação do cliente. O W3C está padronizando isso como Eventos Enviados pelo Servidor usando um text/event-streamtipo MIME. A API do navegador (que é bastante semelhante à API WebSocket) é chamada de API EventSource.
  • Envio de cometa / servidor : este é um termo abrangente que inclui tanto pesquisas longas quanto streaming HTTP. As bibliotecas de cometas geralmente suportam várias técnicas para tentar maximizar o suporte entre navegadores e entre servidores.
  • WebSockets : um TCP interno da camada de transporte que usa um handshake de atualização amigável para HTTP. Diferente do TCP, que é um transporte de streaming, o WebSockets é um transporte baseado em mensagens: as mensagens são delimitadas na conexão e são remontadas na íntegra antes da entrega ao aplicativo. As conexões WebSocket são bidirecionais, full-duplex e de longa duração. Após a solicitação / resposta inicial do handshake, não há semântica transacional e há muito pouco por sobrecarga de mensagem. O cliente e o servidor podem enviar mensagens a qualquer momento e devem lidar com o recebimento de mensagens de forma assíncrona.
  • SPDY : uma proposta iniciada pelo Google para estender o HTTP usando um protocolo de conexão mais eficiente, mas mantendo toda a semântica do HTTP (solicitação / resposta, cookies, codificação). O SPDY apresenta um novo formato de estrutura (com quadros com prefixo de comprimento) e especifica uma maneira de colocar em camadas pares de solicitação / resposta HTTP na nova camada de estrutura. Cabeçalhos podem ser compactados e novos cabeçalhos podem ser enviados após a conexão ter sido estabelecida. Existem implementações do SPDY no mundo real em navegadores e servidores.
  • HTTP 2.0 : possui objetivos semelhantes ao SPDY: reduz a latência e a sobrecarga do HTTP, preservando a semântica do HTTP. O rascunho atual é derivado do SPDY e define um handshake de atualização e um enquadramento de dados muito semelhante ao padrão WebSocket para handshake e enquadramento. Uma proposta de rascunho alternativa do HTTP 2.0 (httpbis-speed-Mobility) realmente usa WebSockets para a camada de transporte e adiciona a multiplexação SPDY e o mapeamento HTTP como uma extensão WebSocket (as extensões WebSocket são negociadas durante o handshake).
  • WebRTC / CU-WebRTC : propostas para permitir conectividade ponto a ponto entre navegadores. Isso pode permitir uma comunicação de média e máxima latência mais baixa porque o transporte subjacente é SDP / datagrama em vez de TCP. Isso permite a entrega fora de ordem de pacotes / mensagens, o que evita a emissão de picos de latência causados ​​por pacotes descartados, que atrasam a entrega de todos os pacotes subsequentes (para garantir a entrega em ordem).
  • QUIC : é um protocolo experimental destinado a reduzir a latência da Web em relação à do TCP. Na superfície, o QUIC é muito semelhante ao TCP + TLS + SPDY implementado no UDP. O QUIC fornece multiplexação e controle de fluxo equivalente ao HTTP / 2, segurança equivalente ao TLS e semântica de conexão, confiabilidade e controle de congestionamento equivalentes ao TCP. Como o TCP é implementado nos kernels do sistema operacional e no firmware da caixa intermediária, é quase impossível fazer alterações significativas no TCP. No entanto, como o QUIC é construído sobre o UDP, ele não sofre essas limitações. O QUIC foi projetado e otimizado para semântica HTTP / 2.

Referências :

kanaka
fonte
1
>> No entanto, isso não ajuda na latência cliente para servidor, o que exige que uma nova conexão seja estabelecida para cada mensagem de cliente para servidor. - e a transmissão do corpo da resposta? Eu sei, a API XMLHttpRequest não permite isso, mas existe. com o streaming para o servidor, você pode transmitir do lado do cliente.
4sn0k
8
@ Philipp, ele fez uma pergunta que eu estava querendo pesquisar e documentar de qualquer maneira. A questão de WebSockets vs outro mecanismo baseado em HTTP surge com bastante frequência, embora agora exista uma boa referência para se vincular. Mas sim, parece provável que o solicitante estava procurando evidências para apoiar uma noção preconcebida sobre WebSockets vs HTTP, especialmente porque ele nunca selecionou uma resposta nem concedeu a recompensa.
Kanaka
9
Muito obrigado por esta visão geral agradável e precisa dos protocolos.
Martin Meeser
2
O @WardC caniuse.com fornece informações de compatibilidade do navegador (incluindo dispositivos móveis).
Kanaka
3
@ www139, não, no nível do protocolo WebSocket, a conexão permanece aberta até que um lado ou o outro lado feche a conexão. Você também pode precisar se preocupar com o tempo limite do TCP (um problema com qualquer protocolo baseado em TCP), mas qualquer tipo de tráfego a cada minuto ou dois manterá a conexão aberta. De fato, a definição do protocolo WebSocket especifica um tipo de quadro de ping / pong, embora mesmo sem isso você possa enviar um único byte (mais um cabeçalho de dois bytes) e que mantenha a conexão aberta. 2-3 bytes a cada dois minutos não representam um impacto significativo na largura de banda.
Kanaka
130

Você parece assumir que o WebSocket é um substituto para o HTTP. Não é. É uma extensão.

O principal caso de uso do WebSockets são aplicativos Javascript que são executados no navegador da Web e recebem dados em tempo real de um servidor. Jogos são um bom exemplo.

Antes do WebSockets, era o único método para os aplicativos Javascript interagirem com um servidor XmlHttpRequest. Mas elas têm uma grande desvantagem: o servidor não pode enviar dados a menos que o cliente solicite explicitamente.

Mas o novo recurso WebSocket permite que o servidor envie dados sempre que desejar. Isso permite implementar jogos baseados em navegador com uma latência muito menor e sem a necessidade de usar hacks feios, como pesquisas longas do AJAX ou plugins de navegador.

Então, por que não usar HTTP normal com solicitações e respostas transmitidas

Em um comentário para outra resposta, você sugeriu apenas transmitir a solicitação do cliente e o corpo da resposta de forma assíncrona.

De fato, os WebSockets são basicamente isso. Uma tentativa de abrir uma conexão WebSocket a partir do cliente parece uma solicitação HTTP no início, mas uma diretiva especial no cabeçalho (Upgrade: websocket) informa ao servidor para começar a se comunicar nesse modo assíncrono. Os primeiros rascunhos do protocolo WebSocket não foram muito mais do que isso e alguns handshakes para garantir que o servidor realmente entenda que o cliente deseja se comunicar de forma assíncrona. Porém, percebeu-se que os servidores proxy ficariam confusos com isso, porque estão acostumados ao modelo usual de solicitação / resposta do HTTP. Um cenário de ataque em potencial contra servidores proxy foi descoberto. Para evitar isso, era necessário fazer o tráfego do WebSocket parecer diferente de qualquer tráfego HTTP normal. É por isso que as chaves de máscara foram introduzidas noa versão final do protocolo .

Philipp
fonte
>> o servidor não pode enviar dados, a menos que o cliente tenha solicitado explicitamente; O navegador da Web deve iniciar a conexão dos WebSockets ... o mesmo que para XMLHttpRequest
4esn0k 5/13
18
@ 4esn0k O navegador inicia uma conexão com o websocket. Mas, depois de estabelecido, os dois lados podem enviar dados sempre que quiserem. Esse não é o caso do XmlHttpRequest.
Philipp
1
POR QUE isso não é possível com HTTP?
4esn0k
4
@ Philipp, os jogos são um bom exemplo de brilho dos WebSockets. No entanto, não são dados em tempo real do servidor em que você obtém a maior vitória. Você pode obter quase a mesma latência de servidor-> cliente usando HTTP streaming / conexões de longa data. E com solicitações de espera prolongada, os servidores podem enviar efetivamente sempre que tiverem dados, porque o cliente já enviou a solicitação e o servidor está "retendo a solicitação" até que tenha dados. A maior vitória para o WebSockets é com a latência cliente-> servidor (e, portanto, ida e volta). O cliente capaz de enviar quando quiser sem sobrecarga de solicitação é a chave real.
kanaka
1
@ Philipp, outra observação: além de XMLHttpRequest e WebSockets para JavaScript, existem outros métodos para interagir com o servidor, incluindo iframes ocultos e tags de script de pesquisa longa. Veja a página Comet wikipedia para mais detalhes: en.wikipedia.org/wiki/Comet_(programming)
kanaka
27

Uma API REST regular usa o HTTP como protocolo subjacente para a comunicação, que segue o paradigma de solicitação e resposta, significando que a comunicação envolve o cliente solicitando alguns dados ou recursos de um servidor e o servidor respondendo de volta a esse cliente. No entanto, o HTTP é um protocolo sem estado, portanto, todo ciclo de solicitação-resposta terá que repetir as informações de cabeçalho e metadados. Isso gera latência adicional no caso de ciclos de solicitação-resposta repetidos frequentemente.

http

Com o WebSockets, embora a comunicação ainda inicie como um handshake HTTP inicial, são necessárias outras atualizações para seguir o protocolo WebSockets (ou seja, se o servidor e o cliente estiverem em conformidade com o protocolo, pois nem todas as entidades suportam o protocolo WebSockets).

Agora, com o WebSockets, é possível estabelecer uma conexão full duplex e persistente entre o cliente e um servidor. Isso significa que, diferentemente de uma solicitação e uma resposta, a conexão permanece aberta enquanto o aplicativo estiver em execução (por exemplo, é persistente) e, como é full duplex, é possível a comunicação simultânea bidirecional, ou seja, agora o servidor é capaz de iniciar uma comunicação e 'envia' alguns dados ao cliente quando novos dados (nos quais o cliente está interessado) se tornam disponíveis.

websockets

O protocolo WebSockets é estável e permite implementar o padrão de mensagens Publish-Subscribe (ou Pub / Sub), que é o conceito principal usado nas tecnologias em tempo real, nas quais você pode obter novas atualizações na forma de push do servidor sem o cliente que precisa solicitar (atualizar a página) repetidamente. Exemplos desses aplicativos são o rastreamento de localização do carro Uber, notificações push, atualização dos preços da bolsa em tempo real, bate-papo, jogos com vários jogadores, ferramentas de colaboração on-line ao vivo etc.

Você pode conferir um artigo detalhado sobre Websockets, que explica a história deste protocolo, como surgiu, para que é usado e como você pode implementá-lo.

Aqui está um vídeo de uma apresentação que fiz sobre WebSockets e como eles são diferentes do que usar as APIs REST regulares: Padronização e alavancagem do aumento exponencial no fluxo de dados

Srushtika Neelakantam
fonte
24

Para o TL; DR, aqui estão 2 centavos e uma versão mais simples para suas perguntas:

  1. O WebSockets fornece esses benefícios sobre HTTP:

    • Conexão stateful persistente pela duração da conexão
    • Baixa latência: comunicação quase em tempo real entre servidor / cliente devido a nenhuma sobrecarga de restabelecer conexões para cada solicitação, conforme requer o HTTP.
    • Full duplex: servidor e cliente podem enviar / receber simultaneamente
  2. O WebSocket e o protocolo HTTP foram projetados para resolver problemas diferentes, o IE WebSocket foi projetado para melhorar a comunicação bidirecional, enquanto o HTTP foi projetado para ser sem estado, distribuído usando um modelo de solicitação / resposta. Além do compartilhamento das portas por motivos herdados (penetração de firewall / proxy), não há muito em comum para combiná-las em um único protocolo.

Devy
fonte
3
Importante que você mencionou o stateful prazo e apátridas na sua comparação (Y)
Utsav T
15

Por que o protocolo websockets é melhor?

Não acho que possamos compará-los lado a lado como quem é melhor. Não será uma comparação justa simplesmente porque eles estão resolvendo dois problemas diferentes . Seus requisitos são diferentes. Será como comparar maçãs com laranjas. Eles são diferentes.

HTTP é um protocolo de solicitação-resposta. Cliente (navegador) quer alguma coisa, servidor dá. Isso é. Se o cliente de dados desejar for grande, o servidor poderá enviar dados de streaming para anular problemas indesejados do buffer. Aqui, o principal requisito ou problema é como fazer a solicitação dos clientes e como responder aos recursos (texto em hipertexto) que eles solicitam. É aí que o HTTP brilha.

No HTTP, apenas a solicitação do cliente. O servidor responde apenas.

O WebSocket não é um protocolo de solicitação-resposta em que apenas o cliente possa solicitar. É um soquete (muito semelhante ao soquete TCP). Quando a conexão é aberta, ambos os lados podem enviar dados até que a conexão TCP sublinhada seja fechada. É como um soquete normal. A única diferença com o soquete TCP é que o websocket pode ser usado na web. Na web, temos muitas restrições para um soquete normal. A maioria dos firewalls bloqueia outras portas além das 80 e 433 usadas pelo HTTP. Proxies e intermediários também serão problemáticos. Portanto, para tornar o protocolo mais fácil de implantar no soquete da infraestrutura existente, use o handshake HTTP para atualizar. Isso significa que, quando a conexão for aberta pela primeira vez, o cliente enviou uma solicitação HTTP para informar ao servidor dizendo "Isso não é uma solicitação HTTP, atualize para o protocolo websocket".

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Depois que o servidor entende a solicitação e atualiza-o para o protocolo websocket, ele não é mais aplicado.

Então, minha resposta é: Nenhum dos dois é melhor que o outro. Eles são completamente diferentes.

Por que foi implementado em vez de atualizar o protocolo http?

Bem, podemos fazer tudo sob o nome chamado HTTP também. Mas vamos? Se são duas coisas diferentes, vou preferir dois nomes diferentes. O mesmo acontece com Hickson e Michael Carter .

FranXho
fonte
6

As outras respostas não parecem abordar um aspecto-chave aqui, e você não menciona a necessidade de oferecer suporte a um navegador da Web como cliente. A maioria das limitações do HTTP simples acima pressupõe que você estaria trabalhando com implementações de navegador / JS.

O protocolo HTTP é totalmente capaz de comunicação full-duplex; é legal que um cliente execute um POST com transferência de codificação em partes e um servidor para retornar uma resposta com um corpo de codificação em partes. Isso removeria a sobrecarga do cabeçalho apenas no momento do init.

Portanto, se tudo o que você procura é full-duplex, controla o cliente e o servidor e não está interessado em recursos / estruturas extras dos websockets, então eu argumentaria que o HTTP é uma abordagem mais simples com menor latência / CPU (embora a latência realmente diferiria em microssegundos ou menos em ambos).

parity3
fonte