Websocket API para substituir REST API?

101

Tenho uma aplicação cuja função principal funciona em tempo real, através de websockets ou long polling.

No entanto, a maior parte do site é escrita de forma RESTful, o que é bom para aplicativos e outros clientes no futuro. No entanto, estou pensando em fazer a transição para uma API de websocket para todas as funções do site, longe do REST. Isso tornaria mais fácil para mim integrar recursos em tempo real em todas as partes do site. Isso tornaria mais difícil construir aplicativos ou clientes móveis?

Descobri que algumas pessoas já estão fazendo coisas como esta: SocketStream

atormentar
fonte
2
A pesquisa longa da @Stegi funciona bem o suficiente como uma alternativa, sem se preocupar muito com isso.
Harry
2
Harry agora depois de 7 anos, como funcionou para você? Imaginando, já que quero me mover nessa direção também. @Harry
Dmitry Kudryavtsev
2
@DmitryKudryavtsev Acabei não fazendo isso. O método tradicional funcionou bem para mim e não foi muito mais difícil.
Harry

Respostas:

97

Não quer dizer que as outras respostas aqui não tenham mérito, elas trazem alguns pontos positivos. Mas vou contra o consenso geral e concordo com você de que mudar para websockets para além de recursos em tempo real é muito atraente.

Estou pensando seriamente em mover meu aplicativo de uma arquitetura RESTful para um estilo mais RPC via websockets. Este não é um "app de brinquedo" e não estou falando apenas de recursos em tempo real, então tenho reservas. Mas vejo muitos benefícios em seguir esse caminho e sinto que pode acabar sendo uma solução excepcional.

Meu plano é usar DNode , SocketIO e Backbone . Com essas ferramentas, meus modelos e coleções de Backbone podem ser repassados ​​de / para o cliente e o servidor simplesmente chamando funções no estilo RPC. Chega de gerenciar endpoints REST, serializar / desserializar objetos e assim por diante. Ainda não trabalhei com o socketstream, mas vale a pena conferir.

Ainda tenho um longo caminho a percorrer antes de poder dizer definitivamente que esta é uma boa solução, e tenho certeza que não é a melhor solução para todos os aplicativos, mas estou convencido de que essa combinação seria excepcionalmente poderosa. Admito que existem algumas desvantagens, como perder a capacidade de armazenar recursos em cache. Mas tenho a sensação de que as vantagens as superarão.

Estou interessado em acompanhar seu progresso na exploração desse tipo de solução. Se você tiver algum experimento no github, por favor, me aponte para ele. Ainda não tenho, mas espero que tenha em breve.

Abaixo está uma lista de links para ler mais tarde que venho coletando. Não posso garantir que todos valem a pena, já que apenas dei uma olhada em muitos deles. Mas espero que alguns ajudem.


Ótimo tutorial sobre como usar Socket.IO com Express. Ele expõe sessões expressas para socket.io e discute como ter salas diferentes para cada usuário autenticado.

Tutorial sobre node.js / socket.io / backbone.js / express / connect / jade / redis com autenticação, hospedagem Joyent, etc:

Tutorial sobre como usar o Pusher com Backbone.js (usando Rails):

Construa o aplicativo com backbone.js no cliente e node.js com express, socket.io, dnode no servidor.

Usando Backbone com DNode:

Tauren
fonte
1
Acabei de responder a uma pergunta relacionada e incluí mais alguns pensamentos: stackoverflow.com/questions/4848642/…
Tauren
11
“Ainda tenho um longo caminho a percorrer antes de dizer definitivamente que esta é uma boa solução” - Só por curiosidade, esta foi realmente uma boa solução? : D
inf3rno
7
Por favor, responda @Tauren. Estou muito interessado no que você tem a dizer agora.
No_name de
4
@Tauren Também estou curioso para saber como isso funcionou?
Kurren,
57

HTTP REST e WebSockets são muito diferentes. O HTTP não tem estado , então o servidor da web não precisa saber de nada e você obtém o cache no navegador da web e em proxies. Se você usa WebSockets, seu servidor está se tornando stateful e você precisa ter uma conexão com o cliente no servidor.

Comunicação de solicitação-resposta vs push

Use WebSockets apenas se você precisar enviar dados do servidor para o cliente, esse padrão de comunicação não está incluído no HTTP (apenas por soluções alternativas). PUSH é útil se os eventos criados por outros clientes precisarem estar disponíveis para outros clientes conectados, por exemplo, em jogos onde os usuários devem agir de acordo com o comportamento de outros clientes. Ou se o seu site estiver monitorando algo, onde o servidor envia dados para o cliente o tempo todo, por exemplo, bolsas de valores (ao vivo).

Se você não precisa PUSHar dados do servidor, geralmente é mais fácil usar um servidor HTTP REST sem estado. O HTTP usa um padrão de comunicação simples de solicitação-resposta .

Jonas
fonte
5
Estamos muito acostumados com o padrão de uma direção porque nunca tivemos alternativas antes. Mas agora que meu aplicativo se torna mais desenvolvido, fica mais claro para mim que quanto mais lugares nos quais a tecnologia push é usada, mais responsivo e mais envolvente o aplicativo se torna.
Harry
Meu aplicativo mostra uma lista de amigos e a quantidade de pontos que eles possuem, por exemplo. Por que não atualizá-lo em tempo real. Se os usuários podem ver o progresso de seus amigos, eles podem estar mais inclinados a querer acompanhar. Tenho certos modelos de documento que, embora não sejam exatamente alterados com frequência, são alterados o suficiente para que não atualize em tempo real pode causar uma pequena confusão. Em algum momento, o suficiente do seu site se beneficia de ter atualizações push para que você comece a olhar para o seu código e metade dele é sobre REST e a outra metade é sobre soquetes e você diz bem, eu quero unificar isso.
Harry
3
É uma opção usar websockets apenas para enviar uma notificação / comando para o seu webapp (como getUpdate ou refreshObjectWithId com params). Esse comando pode ser analisado em seu webapp (cliente) e seguido por uma solicitação de descanso para obter dados específicos em vez de transportar os próprios dados através dos websockets.
Beachwalker
2
Existem muitos motivos pelos quais os websockets podem ser mais fáceis do que chamadas REST - não apenas para push. websocket.org/quantum.html
BT
Os WebSockets são incríveis e liberam o servidor para enviar os dados do cliente a qualquer momento, não apenas em resposta a uma mensagem do cliente. O WebSockets implementa um protocolo baseado em mensagem para que os clientes possam receber mensagens a qualquer momento e, se estiverem esperando por uma mensagem específica, podem enfileirar outras mensagens para processamento posterior, reordenar mensagens enfileiradas, ignorar mensagens enviadas dependendo do estado do aplicativo, etc. Nunca mais escreverei outro aplicativo baseado em REST. O Flash também facilita isso, com implementações de WebSocket de código aberto baseado em AS3 e fallback para o navegador por meio dos métodos ExternalInterface. (AddCallback / call).
Triynko
40

Estou pensando em fazer a transição para uma API WebSocket para todas as funções do site

Não. Você não deve fazer isso. Não há nenhum dano se você oferecer suporte a ambos os modelos. Use REST para comunicação unilateral / solicitações simples e WebSocket para comunicação bidirecional, especialmente quando o servidor deseja enviar notificação em tempo real.

WebSocket é um protocolo mais eficiente do que RESTful HTTP, mas ainda pontua RESTful HTTP sobre WebSocket nas áreas abaixo.

  1. Os recursos de criação / atualização / exclusão foram bem definidos para HTTP. Você deve implementar essas operações em baixo nível para WebSockets.

  2. As conexões WebSocket são dimensionadas verticalmente em um único servidor, enquanto as conexões HTTP são dimensionadas horizontalmente. Existem algumas soluções proprietárias não baseadas em padrões para dimensionamento horizontal WebSocket.

  3. O HTTP vem com muitos recursos bons, como cache, roteamento, multiplexação, gzip, etc. Eles precisam ser construídos sobre o Websocket se você escolher o Websocket.

  4. Otimizações de mecanismo de pesquisa funcionam bem para URLs HTTP.

  5. Todos os proxy, DNS e firewalls ainda não estão totalmente cientes do tráfego do WebSocket. Eles permitem a porta 80, mas podem restringir o tráfego espionando-a primeiro.

  6. A segurança com o WebSocket é uma abordagem tudo ou nada.

Dê uma olhada neste artigo para mais detalhes.

Ravindra babu
fonte
3
Esta é a melhor resposta.
MattWeiler
1
Principal resposta para o tópico
Sanandrea
10

O único problema que consigo usar o TCP (WebSockets) como sua principal estratégia de entrega de conteúdo da web é que há muito pouco material para leitura sobre como projetar a arquitetura e a infraestrutura do seu site usando TCP.

Portanto, você não pode aprender com os erros de outras pessoas e o desenvolvimento será mais lento. Também não é uma estratégia "experimentada e testada".

É claro que você também perderá todas as vantagens do HTTP (ser sem estado e armazenar em cache são as maiores vantagens).

Lembre-se de que HTTP é uma abstração do TCP projetada para servir conteúdo da web.

E não vamos esquecer que SEO e motores de busca não fazem websockets. Então você pode esquecer o SEO.

Pessoalmente, eu não recomendaria isso, pois há muito risco.

Não use WS para servir sites, use-o para servir aplicações web

No entanto, se você tem um brinquedo ou um site pessoal, vá em frente. Experimente, seja o que há de mais moderno. Para uma empresa ou empresa, você não pode justificar o risco de fazer isso.

Raynos
fonte
7

Aprendi uma pequena lição (da maneira mais difícil). Eu fiz um aplicativo de processamento de números que roda em serviços de nuvem Ubuntu AWS EC2 (usa GPUs poderosas) e queria fazer um front-end para ele apenas para observar seu progresso em tempo real. Devido ao fato de que precisava de dados em tempo real, era óbvio que eu precisava de websockets para enviar as atualizações.

Tudo começou com uma prova de conceito e funcionou muito bem. Mas então, quando queríamos disponibilizá-lo ao público, tivemos que adicionar a sessão do usuário, então precisamos de recursos de login. E não importa como você olhe para isso, o websocket precisa saber com qual usuário ele lida, então pegamos o atalho de usar os websockets para autenticar os usuários . Parecia óbvio e conveniente.

Na verdade, tivemos que passar algum tempo em silêncio para tornar as conexões confiáveis. Começamos com alguns tutoriais de websocket baratos, mas descobrimos que nossa implementação não foi capaz de se reconectar automaticamente quando a conexão foi interrompida. Tudo isso melhorou quando mudamos para o socket-io. Socket-io é um must!

Dito tudo isso, para ser honesto, acho que perdemos alguns ótimos recursos do socket-io. O Socket-io tem muito mais a oferecer e tenho certeza de que, se você levar isso em consideração em seu design inicial, poderá obter mais com ele. Em contraste, acabamos de substituir os velhos websockets pela funcionalidade de websocket do socket-io, e foi isso. (sem salas, sem canais, ...) Um redesenho poderia ter tornado tudo mais poderoso. Mas não tínhamos tempo para isso. Isso é algo para lembrar em nosso próximo projeto.

Em seguida, começamos a armazenar mais e mais dados (histórico do usuário, faturas, transações, ...). Armazenamos tudo isso em um banco de dados dynamodb da AWS e, NOVAMENTE, usamos o socket-io para comunicar as operações CRUD do front-end para o back-end. Acho que pegamos o caminho errado aí. Isso foi um erro.

  • Porque logo depois descobrimos que os serviços em nuvem da Amazon (AWS) oferecem ótimas ferramentas de balanceamento de carga / dimensionamento para aplicativos RESTful .
  • Temos a impressão de que precisamos escrever muito código para realizar os handshakes das operações CRUD.
  • Recentemente, implementamos a integração com o Paypal. Conseguimos fazer funcionar. Mas, novamente, todos os tutoriais estão fazendo isso com APIs RESTful . Tivemos que reescrever / repensar seus exemplos para implementá-los com websockets. Mas conseguimos fazer funcionar bem rápido. Mas parece que estamos indo contra o fluxo.

Tendo dito tudo isso, vamos ao ar na próxima semana. Chegamos a tempo, tudo funciona. E é rápido, mas vai escalar?

bvdb
fonte
Apenas imaginando, enquanto tentamos tomar essa decisão por conta própria, ela foi bem dimensionada com a AWS?
Gabe
1
@Gabe aparentemente o node pode facilmente obter 100 conexões socket-io em uma instância aws barata. Não notamos nenhum problema de desempenho ainda. Um dos efeitos estranhos, porém, é que as pessoas que visitam seu site uma vez, mas deixam o site aberto em uma guia, continuam a usar conexões. (e isso acontece com frequência em telefones celulares). Portanto, você precisa de pelo menos um tipo de mecanismo para expulsar usuários ociosos. Eu ainda não me esforcei para fazer isso, pois nosso desempenho não é afetado por isso. - Então, nenhuma escalada foi necessária ainda.
bvdb
4

Eu consideraria usar ambos . Cada tecnologia tem seu mérito e não existe uma solução única para todos.

A separação do trabalho é assim:

  1. WebSockets seria o método principal de um aplicativo para se comunicar com o servidor onde uma sessão é necessária. Isso elimina muitos hacks que são necessários para os navegadores mais antigos (o problema é o suporte para os navegadores mais antigos que eliminarão isso)

  2. A API RESTful é usada para chamadas GET que não são orientadas à sessão (ou seja, não são necessárias autenticação) que se beneficiam do cache do navegador. Um bom exemplo disso seriam os dados de referência para menus suspensos usados ​​por um aplicativo da web. Contudo. pode mudar um pouco mais frequentemente do que ...

  3. HTML e Javascript. Eles incluem a IU do webapp. Geralmente, eles se beneficiariam ao serem colocados em um CDN.

  4. Os Web Services que usam WSDL ainda são a melhor forma de comunicação corporativa e entre empresas, pois fornecem um padrão bem definido para a passagem de mensagens e dados. Primeiramente, você descarregaria isso para um dispositivo Datapower para proxy para seu manipulador de serviço da web.

Tudo isso acontece no protocolo HTTP, que já permite o uso de soquetes seguros via SSL.

Para o aplicativo móvel, entretanto, os websockets não podem se reconectar a uma sessão desconectada ( como reconectar ao websocket após fechar a conexão ) e gerenciar isso não é trivial. Portanto, para aplicativos móveis , eu ainda recomendaria a API REST e a pesquisa.

Outra coisa a se observar ao usar WebSockets vs REST é a escalabilidade . As sessões do WebSocket ainda são gerenciadas pelo servidor. A API RESTful, quando feita corretamente, é sem estado (o que significa que não há estado do servidor que precise ser gerenciado), portanto, a escalabilidade pode crescer horizontalmente (o que é mais barato) do que verticalmente .

Arquimedes Trajano
fonte
2

Eu quero atualizações do servidor?

  • Sim: Socket.io
  • Não: REST

As desvantagens do Socket.io são:

  • Escalabilidade: WebSockets requerem conexões abertas e uma configuração de operações muito diferente para escala web.
  • Aprendizagem: Não tenho tempo ilimitado para meu aprendizado. As coisas têm que ser feitas!

Ainda usarei o Socket.io em meu projeto, mas não para formulários da web básicos que REST fará bem.

Michael Cole
fonte
1

Os transportes baseados em WebSockets (ou long polling) servem principalmente para comunicação (quase) em tempo real entre o servidor e o cliente. Embora existam vários cenários em que esses tipos de transporte são necessários, como bate-papo ou algum tipo de feed em tempo real ou outras coisas, nem todas as partes de algum aplicativo da web precisam estar necessariamente conectadas bidirecionalmente ao servidor.

REST é uma arquitetura baseada em recursos que é bem compreendida e oferece seus próprios benefícios sobre outras arquiteturas. WebSockets inclinam-se mais para streams / feeds de dados em tempo real, o que exigiria que você crie algum tipo de lógica baseada em servidor para priorizar ou diferenciar entre recursos e feeds (caso você não queira usar REST).

Suponho que eventualmente haveria mais estruturas centradas em WebSockets como socketstream no futuro, quando este transporte fosse mais difundido e melhor compreendido / documentado na forma de entrega agnóstica de tipo / formulário de dados. No entanto, eu acho que isso não significa que ele iria / deveria substituir o REST apenas porque ele oferece funcionalidade que não é necessariamente necessária em vários casos de uso e cenários.

yojimbo87
fonte
-1

Isso não é uma boa idéia. O padrão ainda nem está finalizado, o suporte varia entre os navegadores, etc. Se você quiser fazer isso agora, vai acabar precisando voltar para o flash ou long polling, etc. No futuro provavelmente ainda não fará um faz muito sentido, uma vez que o servidor tem que suportar deixar conexões abertas para cada usuário. Em vez disso, a maioria dos servidores web são projetados para se destacarem em responder rapidamente a solicitações e fechá-las o mais rápido possível. Caramba, até mesmo seu sistema operacional teria que ser ajustado para lidar com um grande número de conexões simultâneas (cada conexão usando mais portas efêmeras e memória). Limite-se a usar REST para o máximo possível do site.

zeekay
fonte
Sim, a maioria dos webserves é excelente em HTTP. Mas node.js não é um servidor web, é uma biblioteca io. Ele pode fazer o TCP muito bem. A questão é basicamente dizer se podemos projetar sites para usar TCP em vez de HTTP.
Raynos
As mesmas restrições se aplicam, você ainda ficará sem portas / memória efêmeras, ainda limitará quantas pessoas você pode servir simultaneamente e sobrecarregará desnecessariamente o sistema.
zeekay
sim, há um limite, mas não acho que seja grande coisa se você não criar um novo thread por conexão.
Raynos
Já tenho um soquete para cada usuário. chat global + news feed.
Harry
1
Acho que em 2011 essa foi uma ótima resposta. - Então, eu vejo de onde você está vindo. Mas em 2019, os websockets amadureceram.
bvdb