Compartir a través de


Este artículo proviene de un motor de traducción automática.

Tecnología de vanguardia

Long Polling y SignalR

Dino Esposito

 

Dino EspositoEstamos construyendo más y más sofisticadas aplicaciones Web de un protocolo que, paradójicamente, fue concebido y diseñado para mucho más simples formas de interacción. HTTP no tiene ninguna compatibilidad integrada para el Estado o incluso seguridad. Su supuesto básico es que el cliente hace una solicitud y el servidor Web emite una respuesta. En suma, significa que ninguna petición, ninguna respuesta.

Dada la penetración actual de la Web y la ubicuidad de soluciones Web, cambiar los pilares de la Web (HTTP, HTML, JavaScript) está fuera de la cuestión. ¿Pero deberíamos considerar mejorar algunos de esos pilares? Por supuesto. Aplicaciones modernas tienen requisitos específicos que empujan los protocolos Web y lenguajes a su límite, o más allá.

En los últimos tramos de esta columna, hablé de una aplicación artesanal de un mecanismo que sondea el servidor e informa de los cambios al cliente. El mes pasado, aplicado la misma idea utilizando los servicios de una biblioteca emergente: SignalR. Te proporcionan ahora una breve descripción de las técnicas y un resumen de las opciones que tiene actualmente. Voy a poner SignalR en el centro de atención y mirar su aplicación — y algunos de su magia.

Consideraciones de sondeo

Dada la restricción de solicitudes y respuestas HTTP, el sondeo es el único camino posible para establecer una comunicación directo entre un cliente y un servidor Web. El cliente empuja las solicitudes a su conveniencia y el servidor responde con diligencia. La clave para evaluar la eficacia de sondeo es el verdadero significado de que asignar a la expresión "a"su conveniencia. Siempre hay una solicitud de cliente en el centro de cualquier solución basada en sondeo. La solicitud se levanta hasta que el servidor ha respondido. Cualquier solicitud pendiente consume una conexión de explorador y, más importante aún, contrata a un subproceso de servidor, haciendo de ese valioso recurso disponible para otras solicitudes. En resumen, demasiado frecuentes solicitudes generar presión en el servidor Web.

¿Pero no es la capacidad del servidor para manejar un número creciente de solicitudes de la idea de escalabilidad? De hecho, sondeo no crea nuevos problemas de escalabilidad, pero añade un número considerable de nuevas solicitudes al servidor que debe tenerse en cuenta para asegurar un servidor escalable y de alto rendimiento. Vamos a ver cómo nos podríamos implementar mesas electorales.

Sondeo de AJAX

En mi diciembre de 2011 (msdn.microsoft.com/magazine/hh580729) y enero de 2012 (msdn.microsoft.com/magazine/hh708746) columnas, presenté un marco para controlar el progreso de una operación remota. Todo el marco se basa en las llamadas AJAX. En primer lugar, el cliente invoca un extremo de servidor para iniciar una tarea potencialmente prolongada; a continuación, configura un temporizador para colocar llamadas simultáneas al otro extremo cada 500 milisegundos. Como la tarea de servidor hace su trabajo, actualiza una ubicación conocida. El extremo de servidor que ha invocado periódicamente simplemente busca datos en esa ubicación y devuelve cualquier contenido que encuentre al cliente.

Este patrón de AJAX-sondeo funciona de maravilla y es ampliamente empleado en muchos escenarios de la industria. Mayoría de los sitios que proporcionan noticias o resultados en vivo seguir este patrón. En mis artículos, simplemente lo adaptado el patrón para el escenario específico de vigilar el progreso de una operación remota.

Al final, el problema con el sondeo de AJAX es averiguar el intervalo de actualización correcta: uno que representa un buen equilibrio entre la presión en el servidor y exactitud de la información informó a los usuarios. Una solución eficaz de AJAX-sondeo da un significado concreto a "en el cliente conveniencia" en el envío de las solicitudes.

Sondeo largo

Antes de AJAX, desarrolladores utilizan la actualización de meta tag HTML para instruir a los navegadores para actualizar una página cada determinado número de segundos. Con votación de AJAX, lograr la misma cosa, pero en una forma mucho más suave.

Para un creciente número de aplicaciones, sin embargo, esta forma de sondeo no basta. Sondeo de AJAX casi inevitablemente introduce un retardo entre la ocurrencia de un evento en el servidor y la notificación del evento para el cliente. Ajustando la frecuencia de las actualizaciones, puede trabajar con buenas soluciones, sin embargo, sondeo de AJAX no puede entregar esa conexión constante y continuo que muchas aplicaciones (principalmente sociales) parecen necesitar hoy.

La solución de estos días parece ser largo de sondeo. Curiosamente, cuando AJAX surgió hace años, sondeo de AJAX más inteligente sustituye largo sondeo porque éste no fue muy efectivo en la Web. Tiempo de sondeo es realiza a través de la Web las mismas cosas que hacer en un escenario de escritorio. Con largas mesas electorales, el cliente coloca la solicitud y el servidor no responde hasta que tenga información para volver. El cliente Web mantiene una conexión pendiente que se cierra sólo cuando se puede devolver una respuesta válida. Eso es exactamente lo que desea en la actualidad, excepto que tiene el potencial de frenar el servidor Web.

Tiempo de sondeo coloca un menor número de solicitudes al servidor en comparación con el sondeo de AJAX, pero cada solicitud podría tomar mucho más tiempo. Con el tiempo, esto puede ser perjudicial para la salud del servidor Web porque mantiene subprocesos de servidor dedicados hasta puede generarse una respuesta. Con menos subprocesos disponibles en un momento dado, el servidor Web inevitablemente obtiene más lento en lo responder a las solicitudes de otras recibe. Para ser eficaz, largo sondeo necesita algunos trabajos de aplicación seria y avanzadas habilidades de programación multiproceso y paralelos. Así, durante años, largo sondeo no era realmente una opción, pero no importa porque no había ninguna demanda de conectividad continua.

Hoy, con la tarea de biblioteca paralelo en Microsoft.NET Framework 4 y otras instalaciones en ASP.NET para crear controladores HTTP asincrónicos, largos de sondeo se ha convertido en una opción viable. En general, es aún más difícil que un marco de AJAX-sondeo correspondiente preseas en un marco de largo-sondeo. Necesita un entorno de servidor bien diseñados que no gravar el servidor Web y un entorno de cliente que puede soportar largas de sondeo. Tiempo de sondeo, de hecho, se refiere a una operación de cliente/servidor de macro que se desarrolla en la Web y necesariamente en un número de paquetes de solicitud y respuesta HTTP clásicos. El cliente debe ser lo suficientemente inteligente como para emitir una nueva solicitud de inmediata hasta que finalice la operación de macro. Podrá volver a este punto más adelante.

SignalR al rescate

SignalR es un entorno de Microsoft diseñado para facilitar la comunicación cliente/servidor en tiempo real. Proporciona una implementación eficaz de largo sondeo no tiene un profundo impacto en el servidor y al mismo tiempo asegura que los clientes se actualizan adecuadamente acerca de lo que ocurre forma remota. Figura 1muestra un extracto del código que presenté en mi última columna. La clase BookingHub es el método que se invoca desde el explorador de Web para iniciar la operación de macro "reserva del vuelo".

Clase de SignalR de la figura 1 que realiza una operación de Multistep

public class BookingHub : Hub
{
  public void BookFlight(String from, String to)
  {
    // Book first leg
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", from, to));
    BookFlightInternal(from, to);
    // Book return
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", to, from));
    BookFlightInternal(to, from);
    // Book return
    Clients.displayMessage("Charging credit card ...");
    ChargeCreditCardInternal();
    // Some return value
    Clients.displayMessage("Flight booked successfully.");
  }
}

Esto es claramente una operación multietapa, y a cada paso la clase envía una notificación al cliente. ¿Cuántas solicitudes HTTP están implicadas? Echemos un vistazo con Fiddler (véase figura 2).

The Full Stack of HTTP Requests for the Flight-Booking Operation
Figura 2 la pila completa de peticiones HTTP para la operación de reserva de vuelo

Dentro de una operación de SignalR

La primera solicitud se activa cuando se llama el método de inicio desde la página del cliente; Esto identifica al cliente al SignalR back-end. Cabe señalar que la primera solicitud es una solicitud especial de negociación. Siempre será AJAX independientemente del transporte final negociado para la conexión. Cualquier página SignalR Web incluye código como el siguiente que se ejecuta cuando se carga una página:

$(function () {
  var bookingHub = $.connection.bookingHub;
  bookingHub.start();
}

De esta manera, la página declara su intención de abrir una conexión para invocar los servicios del objeto del servidor bookingHub. Tenga en cuenta que es SignalR que hace la magia de la creación de un objeto de cliente según la interfaz pública del objeto servidor concentrador. El nombre del objeto JavaScript coincide con el nombre del objeto de servidor. Sin embargo, puede utilizar el atributo HubName para modificar el nombre usado en el cliente:

[HubName("booking")]
public class BookingHub : Hub
{
  ...
}

La solicitud de inicio devuelve un ID de cliente, el cliente pasará junto con las solicitudes sucesivas.

{"Url":"/signalr","connectionId":"2a119962-edf7-4a97-954b-e74f2f1d27a9"}

A continuación, la biblioteca de cliente coloca otra solicitud de conexión. Se trata de la solicitud de "conectar", que dará como resultado el evento OnConnect se plantea para la conexión en el servidor. Figura 3 muestra un par de solicitudes de conexión.

Reiterating Connection Requests
Figura 3 reiterando las solicitudes de conexión

La primera terminada en dos minutos; el segundo está aún pendiente. Esta es la esencia de largo sondeo: el cliente tiene un canal abierto continuamente con el servidor. El servidor veces la solicitud después de dos minutos si ninguna acción se realiza en el servidor que requiere enviar datos al cliente. En la solicitud de reserva de vuelo IU, hay un botón que el usuario puede hacer clic para empezar a reservar el vuelo. Cuando el usuario hace clic en el botón se ejecuta el siguiente código:

bookingHub.bookFlight("fco", "jfk");

Si ha creado la aplicación de ejemplo de la columna del mes pasado, debería han vinculado este código al controlador de clic en el botón de página.

El objeto bookingHub pertenece a una secuencia de comandos SignalR descargas a través de la URL signalr y concentradores, como se muestra en figura 3. bookingHub es un objeto proxy normal que oculta la complejidad de la implementación de un patrón de sondeo de largo. Haga clic en el botón desencadena una nueva solicitud en el servidor donde está incrustado el ID de cliente. Cuando el servidor recibe una llamada de un cliente que tiene una llamada pendiente, termina la llamada pendiente y comienza a procesar la solicitud nueva, como se muestra en figura 4.

A Multistep Operation Is Taking Place
Figura 4 multietapa operación está teniendo lugar

Figura 4 muestra una solicitud pendiente (signalr/enviar), dos solicitudes completadas y otro pendiente de solicitud. El signalr y enviar una solicitud es el llamado original a la operación de macro para reservar el vuelo, cuyo código fuente se muestra en la figura 1.

El código de figura 1 llama al cliente en diversas etapas para notificar de cualquier progreso, así:

Clients.displayMessage(...);

Al mismo tiempo que se coloca una solicitud de signalr/enviar, otra solicitud empieza a esperar para las notificaciones. Esta solicitud de espera hasta que hay algunos datos para volver a enviar. Cualquier llamada a clientes en el código de servidor completa la solicitud de notificación y desencadena inmediatamente otro desde el cliente, por lo que la secuencia figura 4 significa que se han completado dos pasos y se han recibido dos mensajes de progreso por parte del cliente. El proceso de servidor ahora está ocupado tratando de conseguir el tercer paso. Al final del código de figura 1, todas las solicitudes en figura 4 habrá completado y la situación volverá a uno similar a lo que se muestra en figura 2.

Más allá de sondeo largo

Si se compara el comportamiento de largo sondeo implementado en SignalR con los pasos que he indicado en mis artículos acerca de sondeo de AJAX, debería reconocer un patrón común: el patrón de indicador de progreso. AJAX sondeo y largo sondeo es dos implementaciones diferentes de la misma pauta. Que uno es más eficaz depende de la configuración del servidor Web y requisitos de la aplicación. Es la llamada. En cualquier caso, si opta por sondeo largo, necesita SignalR o una biblioteca análoga. Si desea construir su propio marco, sugiero optar por las llamadas rápidamente numerosos pero de sondeo de AJAX frente a las menor pero más llamadas de larga de sondeo.

Creación de un marco eficaz de largo-sondeo puede ser complicado. Con votación de AJAX probablemente no obtendrá conectividad continua, pero también no riesgo ralentizar el servidor. Con esto en mente, yo probablemente no vaya y actualizar cualquier servidor Web en tiempo real que cuidar a SignalR. Sin embargo, una vez SignalR es liberado, no ve ninguna razón para no usarla para nuevas aplicaciones.

Por último, cabe mencionar que SignalR ahora soporta otros transportes nivel superior además de sondeo largo. En la última fuente, también encontrar apoyo para WebSockets en servidores de Windows 8; Servidor envía eventos en Chrome, Firefox, Opera y Safari; y siempre que se enmarque en Internet Explorer. La biblioteca se inicia al principio de la lista y sigue cayendo atrás hasta que se encuentre un transporte compatible. Así, al final, tiempo de sondeo realmente rara vez se utilizará en la mayoría de los casos.

Dino Esposito es autor de "Programación ASP.NET 4" (Microsoft Press, 2011) y "Programming ASP.NET MVC 3" (Microsoft Press, 2010), y coautor de "Microsoft .NET: Architecting Applications for the Enterprise" (Microsoft Press , 2008). Con residencia en Italia, Esposito participa habitualmente en conferencias y eventos del sector en todo el mundo. Seguirlo en Twitter en Twitter.com/despos.

Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Damian Edwards