¿Es el rendimiento la única razón para no usar SignalR (websockets) en lugar de una API REST tradicional?

42

Solía SignalRlograr la funcionalidad de mensajería en tiempo real en varios de mis proyectos. Parece funcionar de manera confiable y es muy fácil de aprender a usar.

La tentación, al menos para mí, es abandonar el desarrollo de un servicio de API web y usarlo SignalRpara todo.

Siento que esto podría lograrse mediante un diseño atento, y si lo fuera, significaría que sería necesario mucho menos código de cliente. Más importante aún, significaría que habría una única interfaz para los servicios en lugar de una interfaz dividida, y en el peor de los casos, que uno podría conectar esto sin pensar en cuándo se renderizarán las cosas, etc.

Entonces, me gustaría saber:

  1. ¿Hay alguna otra razón para no usar SignalR en lugar de todos los servicios web además del rendimiento?
  2. ¿El rendimiento de SignalR es lo suficientemente preocupante como para que no tenga sentido hacerlo?

Siempre ha sido un sueño para mí poder traducir las definiciones de objetos y servicios del lado del servidor al código de acceso al servicio del lado del cliente sin algo tonto node.js. Por ejemplo, si defino un objeto interesante InterestingObjecty un servicio para CRUDel objeto InterestingObjectService, puedo definir una ruta URL estándar al servicio, por ejemplo, "/ {serviceName} / {methodName}", pero aún necesito escribir el código del cliente para acceder el servicio. Dado que el objeto se va a pasar de cliente a servidor y viceversa, no hay ninguna razón práctica para tenerdefinir el objeto explícitamente en el código del lado del cliente, ni debería existir la necesidad de definir explícitamente las rutas para realizar operaciones CRUD. Siento que debería haber una manera de estandarizar todo esto para que sea posible escribir un cliente bajo el supuesto de que el acceso al servicio funciona desde el cliente al servidor y viceversa tan transparente como lo haría si estuviera escribiendo un WinForms o Java Aplicación Applet o Native o lo que tengas.

Si SignalR es lo suficientemente bueno como para usarlo en lugar de un servicio web tradicional, puede ser una forma viable de lograrlo. SignalR ya incluye la funcionalidad para hacer que el centro funcione como el servicio que describo, por lo que podría definir un servicio de base común (CRUD) que ofrezca toda esta funcionalidad de forma inmediata con cierta reflexión. Entonces casi podría dar por sentado el acceso al servicio, ahorrándome la molestia de volver a escribir código para acceder a algo a lo que se podía acceder por convención, y lo que es más importante, el tiempo que tendría que pasar escribiendo código para definir cómo se actualiza esto en el DOM

Después de leer mi edición, siento que puede ser un poco absurdo, así que no dudes en preguntarme si tienes preguntas sobre a qué me refiero. Básicamente, quiero que el acceso al servicio sea lo más transparente posible.

tacos_tacos_tacos
fuente
55
Si tiene una tarjeta de red mágica que puede mantener abiertos un número infinito de sockets y una red mágica que puede soportar una cantidad infinita de ancho de banda y un servidor mágico que tiene una cantidad infinita de memoria y ciclos de CPU, ¡entonces Websockets solo es una gran opción!
Csla hace lo que quiere, los objetos de negocios pueden moverse entre el cliente y el servidor.
Andy

Respuestas:

50

Esas dos tecnologías tienen un propósito muy diferente.

  • REST es para llamadas ordinarias a una API, siendo el cliente un actor activo del intercambio. Cuando el cliente necesita encontrar las coordenadas GPS de una dirección, el cliente inicia la llamada a la API y espera hasta que recibe las coordenadas, o se produce un error, o transcurre el tiempo de espera.

  • Los sockets web son para todo lo que necesita hacer las cosas al revés. Por ejemplo, cuando uso un sitio web de intranet que me muestra en tiempo real los registros y el rendimiento de diferentes servidores, el cliente puede ser pasivo y esperar hasta que el servidor le envíe un mensaje de registro o una métrica de rendimiento recién publicado.

La diferencia es clara: en el primer caso, el cliente decide cuándo necesita una información específica; En el segundo caso, el cliente simplemente espera a ser contactado y puede no saber cuándo sería.

De alguna manera, ambos son intercambiables: puede implementar sockets web cuando no los necesite (es decir, el cliente llamará al servidor a través de sockets web en lugar de hacer una llamada REST) ​​y puede usar sondeo o sondeo largo como sustituto de sockets web (dado que esto se usó con éxito durante años hasta que los sockets web se hicieron tan populares).

Pero su intercambiabilidad tiene un costo:

  • Cuando utiliza sondeo o sondeo largo en lugar de sockets web, a menudo está desperdiciando ancho de banda.

  • Cuando utiliza sockets web para hacer lo que se puede hacer a través de la API web, mantiene abiertas todas las conexiones de todos los clientes activos, lo que puede no ser lo que realmente desea. Para un sitio web pequeño donde espera tener un máximo de 5 clientes al mismo tiempo, esto no es un problema. Para un servicio como Amazon AWS, esto no sería fácil de resolver técnicamente.

No use sockets web cuando no los necesite. Para obtener las coordenadas GPS de una dirección, no gano nada al abrir la conexión de sockets web, hacer la llamada, esperar una respuesta y cerrar la conexión: REST satisface mis necesidades para tales escenarios.

  • Si se encuentra buscando información de forma repetida y frecuente a través de una llamada REST a un servicio, esto puede ser una buena señal de que debe pasar a los sockets web. Del mismo modo, el desbordamiento de pila reduce el uso de ancho de banda mediante el uso de sockets web, ya que ayuda a las personas a no perder el tiempo presionando F5 en la página de inicio para ver si tienen mensajes nuevos.

  • Si descubre que abre conexiones de sockets web, úselas para hacer una sola llamada y luego ciérrelas, o si sus conexiones permanecen abiertas pero el servidor está enviando algo al cliente solo a pedido del cliente, cambie a REST.

Además, los sockets web todavía tienen un soporte limitado y no siempre son fáciles de implementar. Si bien SignalR facilita su implementación, esto no significa que no tendrá dificultades para implementarlo en otros idiomas / contextos / entornos. Con REST, eso es fácil: puede ser una curlllamada o una función similar disponible en todos los idiomas principales. Con los sockets web, no puede estar seguro de cuánto tiempo se necesitaría para hacer que un cliente use [inserte el nombre de un idioma que aún no conoce aquí].

He usado sockets web en varios proyectos en .NET, Python y node.js.

  • En .NET, no fue demasiado difícil, pero aún así, pasé algunos días tratando de resolver algunos problemas crípticos, como la conexión se cortó tan pronto como se abrió. (Esto fue antes de SignalR; nunca probé SignalR). También usé WCF en modo de sockets web, que tampoco estuvo exento de problemas (pero creo que WCF siempre viene con problemas).

  • En node.js, esto era factible, pero tuve que cambiar dos veces las bibliotecas hasta que encontré una que funcionara. Creo que he pasado al menos una semana tratando de hacer un portal web Hello World.

  • En Python, lo intenté una vez, pasé dos o tres días y abandoné. Nunca funcionó.

Compare esto con REST: el único problema que uno puede encontrar con un nuevo lenguaje / marco es saber cómo PUBLICAR archivos o recibir una respuesta binaria muy grande. Recuerdo que pasé unas horas buscando soluciones para algunos idiomas. Aún así, unas pocas horas para un caso especial no son nada en comparación con días o semanas para un simple Hello World.

Arseni Mourzenko
fuente
2
Votó su respuesta, MainMa, ya que me pareció interesante / útil. Sin embargo, hay un punto que no entiendo. Usted menciona que un pequeño número de clientes está bien para manejar a través de sockets web (por ejemplo, como máximo 5 al mismo tiempo). Luego mencionas que StackOverflow usa sockets web en su página de inicio. ¿Cómo manejan un número tan alto de usuarios? Pregunto porque estoy probando más de 20 conexiones SignalR y encuentro que los retrasos en los mensajes comienzan a aumentar lentamente, antes de que todo se caiga (todo no responde).
gnychis
1
@ gnychis: hay muchas soluciones para eso, pero muchas de ellas están más relacionadas con la infraestructura en sí (para eso está serverfault.com ). En general, arroje más hardware y divida a los usuarios entre dominios, de modo que algunas conexiones sean manejadas por sockets1.example.com, otras por sockets2.example.com, etc. Bastante efectivo pero también bastante costoso en términos de hardware y ancho de banda.
Arseni Mourzenko
3
Esta respuesta es excelente, pero me gustaría limitar la pregunta original. Si una aplicación requiere una conexión websocket continua, entonces ¿por qué no usar websockets completamente en lugar de una API REST? Como un websocket está abierto, tal vez debería utilizarse por completo.
HappyNomad
Acabo de encontrar una respuesta a mi propia pregunta.
HappyNomad
1

Solo mis 2 centavos ...

Creo que no se trata realmente de rendimiento o de ningún tipo. Se trata de estándares. REST es un estándar y en mi humilde opinión tiene las siguientes ventajas:

  • Las solicitudes HTTP son fáciles de usar. Todos pueden usar rápidamente una API REST. Diablos, incluso puede abrir el navegador y escribir una URL para ver los datos, ¿qué tan interactivo puede ser?
  • (Casi) cualquier lenguaje de programación puede usarlo. Es una especie de interfaz universal. La interfaz con SignalR desde un lenguaje exótico parece menos obvio.
  • Tiene un buen soporte de herramientas, como http://petstore.swagger.wordnik.com/
  • Es una buena "interfaz" para depurar. Puede monitorear fácilmente los mensajes entrantes y salientes directamente en el navegador, ver los datos, etc. Con Websockets y bibliotecas personalizadas, no es tan obvio, tiene que registrar explícitamente todo.
dagnelies
fuente
1
Si bien hace algunos buenos comentarios acerca de que las API REST son un poco más sencillas y probablemente tienen mejores herramientas, esta respuesta dice algunas cosas que simplemente no son ciertas. REST no es un estándar , mientras que WebSockets sí lo es .
StriplingWarrior
1
Supongo que fue una mala redacción de mi parte. Lo que quise decir con "estándar" es ser común, ampliamente utilizado, la forma predeterminada de hacer las cosas ... y no "ser un estándar RFC".
Dagnelies
Buena aclaracion. Y, por cierto, Chrome al menos le permite ver el tráfico de WebSockets en sus herramientas de desarrollo. Me imagino que los otros navegadores probablemente también lo hagan.
StriplingWarrior