O desempenho é o único motivo para não usar o SignalR (websockets) inteiramente em vez de uma API REST tradicional?

42

Eu usei SignalRpara obter a funcionalidade de mensagens em tempo real em vários dos meus projetos. Parece funcionar de forma confiável e é muito fácil aprender a usar.

A tentação, pelo menos para mim, é abandonar o desenvolvimento de um serviço de API da Web e usar SignalRpara tudo.

Eu sinto que isso poderia ser alcançado por um design cuidadoso e, se fosse, significaria muito menos código de cliente seria necessário. Mais importante, isso significaria que haveria uma interface única para os serviços, em vez de uma interface dividida, e, na pior das hipóteses, alguém poderia ligar isso sem pensar em quando as coisas seriam renderizadas etc.

Então, eu gostaria de saber:

  1. Existe algum outro motivo para não usar o SignalR em vez de todos os serviços da web, além do desempenho?
  2. O desempenho do SignalR é suficientemente preocupante para que não faria sentido fazê-lo?

Tem sido um sonho meu ser capaz de converter definições de objeto e serviço do lado do servidor em código de acesso de serviço do lado do cliente sem algo parecido node.js. Por exemplo, se eu definir um objeto interessante InterestingObjecte um serviço para CRUDo objeto InterestingObjectService, posso definir uma rota de URL padrão para o serviço - por exemplo, "/ {serviceName} / {methodName}" - mas ainda preciso escrever o código do cliente para acessar o serviço. Como o objeto será passado do cliente para o servidor e vice-versa, não há razão prática para terpara definir o objeto explicitamente no código do lado do cliente, nem deve ser necessário definir explicitamente as rotas para executar operações CRUD. Eu sinto que deveria haver uma maneira de padronizar tudo isso, para que seja possível gravar um cliente com a suposição de que o acesso ao serviço funcione do cliente para o servidor e retorne de forma tão transparente quanto faria se eu estivesse escrevendo um WinForms ou Java Applet ou aplicativo nativo ou o que você tem.

Se o SignalR for bom o suficiente para ser usado no lugar de um serviço da web tradicional, pode ser uma maneira viável de conseguir isso. O SignalR já inclui funcionalidade para fazer o hub funcionar como o serviço que eu descrevo, para que eu possa definir um serviço de base comum (CRUD) que ofereça toda essa funcionalidade pronta para uso com alguma reflexão. Então, eu quase tive como garantido o acesso ao serviço, poupando-me do incômodo de reescrever código para acessar algo que poderia ser acessado por convenção - e, mais importante, o tempo que eu precisaria gastar escrevendo código para definir como isso é atualizado em o DOM.

Depois de ler minha edição, sinto que pode ser um pouco absurdo, então fique à vontade para me perguntar se você tem perguntas sobre o que estou falando. Basicamente, quero que o acesso ao serviço seja o mais transparente possível.

tacos_tacos_tacos
fonte
5
Se você possui uma placa de rede mágica que pode manter aberta um número infinito de soquetes e uma rede mágica que pode suportar uma quantidade infinita de largura de banda e um servidor mágico que possui uma quantidade infinita de memória e ciclos de CPU, então os websockets são apenas uma ótima opção!
Csla faz o que você deseja, os objetos de negócios podem se mover entre cliente e servidor.
Andy

Respostas:

50

Essas duas tecnologias têm um propósito muito diferente.

  • REST é para chamadas comuns a uma API, com o cliente sendo um ator ativo da troca. Quando o cliente precisa encontrar as coordenadas GPS de um endereço, o cliente inicia a chamada para a API e aguarda até receber as coordenadas, ou ocorre um erro ou o tempo limite se esgota.

  • Os soquetes da Web são para tudo que precisa fazer as coisas da maneira oposta. Por exemplo, quando eu uso um site da intranet que mostra em tempo real os logs e o desempenho de diferentes servidores, o cliente pode ser passivo e aguardar até que o servidor envie a ele uma mensagem de log ou métricas de desempenho recém-publicadas.

A diferença é clara: no primeiro caso, o cliente decide quando precisa de uma informação específica; no segundo caso, o cliente simplesmente espera ser contatado e pode não saber quando seria.

De alguma forma, ambos são intercambiáveis: você pode implementar soquetes da Web quando não precisar deles (ou seja, o cliente chamará o servidor através de soquetes da Web em vez de fazer uma chamada REST) ​​e você poderá usar a pesquisa ou a pesquisa longa como um substituto para soquetes da web (considerando que isso foi usado com sucesso por anos até que os soquetes da web se tornaram tão populares).

Mas sua intercambialidade tem um custo:

  • Quando você usa sondagem ou sondagem longa em vez de soquetes da Web, costuma desperdiçar largura de banda.

  • Quando você usa soquetes da web para fazer o que pode ser feito por meio da API da web, mantém todas as conexões de todos os clientes ativos abertos, o que pode não ser o que você realmente deseja. Para um site pequeno em que você espera ter no máximo 5 clientes ao mesmo tempo, isso não é um problema. Para um serviço como o Amazon AWS, isso não seria fácil de resolver tecnicamente.

Não use soquetes da web quando não precisar deles. Para obter as coordenadas GPS de um endereço, não ganho nada ao abrir a conexão de soquetes da web, fazer a ligação, aguardar uma resposta e fechar a conexão: o REST atende às minhas necessidades para tais cenários.

  • Se você encontrar repetidamente e freqüentemente informações por meio de uma chamada REST para um serviço, isso pode ser um bom sinal de que você deve passar para os soquetes da Web. Da mesma forma, o Stack Overflow reduz o uso da largura de banda usando soquetes da Web, pois ajuda as pessoas a não gastar seu tempo pressionando F5 na página inicial para ver se há novas mensagens.

  • Se você achar que abre conexões de soquetes da Web, use-as para fazer uma única chamada e feche-as ou se suas conexões permanecerem abertas, mas o servidor estiver enviando algo ao cliente apenas mediante solicitação do cliente, alterne para REST.

Além disso, os soquetes da web ainda têm um suporte limitado e nem sempre são fáceis de implementar. Embora o SignalR facilite a implementação, isso não significa que você não terá dificuldades para implementá-lo em outros idiomas / contextos / ambientes. Com REST, que é fácil: pode ser uma curlchamada ou um recurso semelhante disponível em todas as línguas mainstream. Com os soquetes da web, você não pode ter certeza de quanto tempo levaria para criar um cliente usando [insira o nome de um idioma que ainda não conhece aqui].

Eu usei web sockets em vários projetos em .NET, Python e node.js.

  • No .NET, não foi muito difícil, mas ainda assim, passei alguns dias tentando descobrir alguns problemas enigmáticos, como a conexão caiu assim que foi aberta. (Isso foi anterior ao SignalR; eu nunca tentei o SignalR). Também usei o WCF no modo de soquetes da web, o que também não ocorreu sem problemas (mas acredito que o WCF sempre vem com problemas).

  • No node.js, isso era possível, mas tive que trocar duas vezes as bibliotecas até encontrar uma que funcionasse. Acredito que passei pelo menos uma semana tentando criar um soquete da web Olá Mundo.

  • Em Python, tentei uma vez, passei dois ou três dias e abandonei. Isso nunca funcionou.

Compare isso com o REST: os únicos problemas que se pode encontrar com uma nova linguagem / estrutura é saber como postar arquivos ou receber uma resposta binária muito grande. Lembro-me de passar algumas horas procurando soluções para alguns idiomas. Ainda assim, algumas horas para um caso especial não são nada comparadas a dias ou semanas para um simples Hello World.

Arseni Mourzenko
fonte
2
Promoveu sua resposta, MainMa, como achei interessante / útil. Há um ponto que eu não entendo. Você menciona que um pequeno número de clientes é aceitável para lidar com soquetes da Web (por exemplo, no máximo 5 ao mesmo tempo). Você menciona que o StackOverflow usa soquetes da web em sua página inicial. Como eles lidam com um número tão alto de usuários? Eu pergunto porque estou tentando mais de 20 conexões SignalR e encontro atrasos nas mensagens lentamente começando a aumentar, antes que tudo caia (tudo não responde).
precisa saber é o seguinte
1
@ gnychis: existem muitas soluções para isso, mas muitas estão mais relacionadas à infraestrutura em si (é para isso que serve serverfault.com ). Em geral, lance mais hardware e divida os usuários entre os domínios, para que algumas conexões sejam tratadas por sockets1.example.com, outras por sockets2.example.com, etc. Bastante eficazes, mas também bastante caras em termos de hardware e largura de banda.
Arseni Mourzenko
3
Essa resposta é excelente, mas eu gostaria de restringir a pergunta original. Se um aplicativo requer uma conexão contínua de websocket, por que não usar websockets inteiramente no lugar de uma API REST? Como um websocket está aberto, talvez deva ser totalmente utilizado.
HappyNomad
Acabei de encontrar uma resposta para minha própria pergunta.
HappyNomad 22/05
1

Apenas meus 2 centavos ...

Eu acho que não é realmente sobre desempenho ou qualquer outra coisa. É sobre padrões. O REST é um padrão e o IMHO tem as seguintes vantagens:

  • As solicitações HTTP são simples de usar. Todos podem usar rapidamente uma API REST. Caramba, você pode até abrir o navegador e digitar um URL para ver os dados. Quão mais interativo você pode ser?
  • (Quase) qualquer linguagem de programação pode usá-lo. É como uma interface universal. A interface com o SignalR de uma linguagem exótica parece menos óbvia.
  • Possui um bom suporte de ferramentas, como http://petstore.swagger.wordnik.com/
  • É uma boa "interface" para depurar. Você pode monitorar facilmente as mensagens recebidas e enviadas diretamente no navegador, ver os dados etc. Com os websockets e as bibliotecas personalizadas, não é tão óbvio que você precisa registrar tudo explicitamente.
dagnelies
fonte
1
Embora você faça alguns bons comentários sobre as APIs REST serem um pouco mais diretas e provavelmente com ferramentas melhores, esta resposta diz algumas coisas que simplesmente não são verdadeiras. REST não é um padrão , enquanto WebSockets é .
StriplingWarrior
1
Eu acho que foi uma redação ruim da minha parte. O que eu quis dizer com "padrão" é ser comum, amplamente utilizado, a maneira padrão de fazer as coisas ... e não "ser um Padrão RFC".
Dagnelies
Bom esclarecimento. E, pelo menos, o Chrome permite que você veja o tráfego do WebSockets em suas ferramentas de desenvolvimento. Eu imagino que os outros navegadores provavelmente também o façam.
StriplingWarrior