Introducción a SignalR

por Patrick Fletcher

Advertencia

Esta documentación no es para la versión más reciente de SignalR. Eche un vistazo a ASP.NET Core SignalR.

En este artículo se describe qué es SignalR y algunas de las soluciones que se diseñaron para crear.

Preguntas y comentarios

Deje sus comentarios sobre cómo le gustó este tutorial y lo que podríamos mejorar en los comentarios de la parte inferior de la página. Si tiene preguntas que no están directamente relacionadas con el tutorial, puede publicarlas en el foro de ASP.NET SignalR o StackOverflow.com.

¿Qué es SignalR?

ASP.NET SignalR es una biblioteca para ASP.NET desarrolladores que simplifican el proceso de agregar funcionalidad web en tiempo real a las aplicaciones. La funcionalidad web en tiempo real es la capacidad de que el código del servidor inserte contenido en los clientes conectados al instante a medida que esté disponible, en lugar de tener que esperar al servidor a que un cliente solicite nuevos datos.

SignalR se puede usar para agregar cualquier tipo de funcionalidad web "en tiempo real" a la aplicación ASP.NET. Aunque el chat se usa a menudo como ejemplo, puede hacer mucho más. Cada vez que un usuario actualiza una página web para ver nuevos datos o la página implementa sondeos largos para recuperar nuevos datos, es un candidato para usar SignalR. Entre los ejemplos se incluyen paneles y aplicaciones de supervisión, aplicaciones de colaboración (como la edición simultánea de documentos), actualizaciones de progreso del trabajo y formularios en tiempo real.

SignalR también permite tipos completamente nuevos de aplicaciones web que requieren actualizaciones de alta frecuencia del servidor, por ejemplo, juegos en tiempo real.

SignalR proporciona una API sencilla para crear llamadas a procedimientos remotos de servidor a cliente (RPC) que llaman a funciones de JavaScript en exploradores cliente (y otras plataformas cliente) desde código .NET del lado servidor. SignalR también incluye la API para la administración de conexiones (por ejemplo, eventos de conexión y desconexión) y las conexiones de agrupación.

Invocar métodos con SignalR

SignalR controla automáticamente la administración de conexiones y permite difundir mensajes a todos los clientes conectados de forma simultánea, como un salón de chat. También se pueden enviar mensajes a clientes concretos. La conexión entre el cliente y el servidor es persistente, a diferencia de una conexión HTTP clásica, que se vuelve a establecer para cada comunicación.

SignalR admite la funcionalidad "inserción de servidor", en la que el código de servidor puede llamar al código de cliente en el explorador mediante llamadas a procedimiento remoto (RPC), en lugar del modelo de solicitud-respuesta común en la web hoy en día.

Las aplicaciones de SignalR se pueden escalar horizontalmente a miles de clientes mediante proveedores integrados y de escalabilidad horizontal de terceros.

Entre los proveedores integrados se incluyen:

Entre los proveedores de terceros se incluyen:

SignalR es de código abierto, accesible a través de GitHub.

SignalR y WebSocket

SignalR usa el nuevo transporte de WebSocket cuando esté disponible y recurra a los transportes más antiguos cuando sea necesario. Aunque ciertamente podría escribir la aplicación mediante WebSocket directamente, el uso de SignalR significa que una gran parte de la funcionalidad adicional que tendría que implementar ya se ha hecho por usted. Lo más importante es que esto significa que puede codificar la aplicación para aprovechar las ventajas de WebSocket sin tener que preocuparse de crear una ruta de acceso de código independiente para clientes anteriores. SignalR también le protege de tener que preocuparse por las actualizaciones de WebSocket, ya que SignalR se actualiza para admitir cambios en el transporte subyacente, lo que proporciona a la aplicación una interfaz coherente entre versiones de WebSocket.

Transportes y reservas

SignalR es una abstracción sobre algunos de los transportes necesarios para realizar un trabajo en tiempo real entre el cliente y el servidor. SignalR primero intenta establecer una conexión WebSocket si es posible. WebSocket es el transporte óptimo para SignalR porque tiene:

  • El uso más eficaz de la memoria del servidor.
  • Latencia más baja.
  • Las características más subyacentes, como la comunicación dúplex completa entre el cliente y el servidor.
  • Los requisitos más estrictos, WebSocket requiere el servidor:
    • Ejecute en Windows Server 2012 o Windows 8.
    • .NET Framework 4.5.

Si no se cumplen estos requisitos, SignalR intenta usar otros transportes para realizar sus conexiones.

Transportes HTML 5

Estos transportes dependen de la compatibilidad con HTML 5. Si el explorador cliente no admite el estándar HTML 5, se usarán transportes más antiguos.

  • WebSocket (si el servidor y el explorador indican que pueden admitir Websocket). WebSocket es el único transporte que establece una conexión bidireccional y persistente verdadera entre el cliente y el servidor. Sin embargo, WebSocket también tiene los requisitos más estrictos; solo se admite en las versiones más recientes de Microsoft Internet Explorer, Google Chrome y Mozilla Firefox, y solo tiene una implementación parcial en otros exploradores, como Opera y Safari.
  • Eventos enviados por el servidor, también conocido como EventSource (si el explorador admite eventos enviados por el servidor, que es básicamente todos los exploradores excepto Internet Explorer).

Transportes de cometas

Los siguientes transportes se basan en el modelo de aplicación web Cometa , en el que un explorador u otro cliente mantiene una solicitud HTTP de larga duración, que el servidor puede usar para insertar datos en el cliente sin que el cliente lo solicite específicamente.

  • Forever Frame (solo para Internet Explorer). Forever Frame crea un IFrame oculto que realiza una solicitud a un punto de conexión en el servidor que no se completa. A continuación, el servidor envía continuamente el script al cliente que se ejecuta inmediatamente, lo que proporciona una conexión unidireccional en tiempo real desde el servidor al cliente. La conexión del cliente al servidor usa una conexión independiente del servidor a la conexión de cliente y, al igual que una solicitud HTTP estándar, se crea una nueva conexión para cada fragmento de datos que se debe enviar.
  • Sondeo largo de Ajax. El sondeo largo no crea una conexión persistente, sino que sondea el servidor con una solicitud que permanece abierta hasta que el servidor responde, momento en el que se cierra la conexión y se solicita inmediatamente una nueva conexión. Esto puede introducir cierta latencia mientras se restablece la conexión.

Para obtener más información sobre qué transportes se admiten en qué configuraciones, consulte Plataformas admitidas.

Proceso de selección de transporte

En la lista siguiente se muestran los pasos que SignalR usa para decidir qué transporte usar.

  1. Si el explorador es Internet Explorer 8 o anterior, se usa sondeo largo.

  2. Si se configura JSONP (es decir, el jsonp parámetro se establece true en cuando se inicia la conexión), se usa sondeo largo.

  3. Si se realiza una conexión entre dominios (es decir, si el punto de conexión de SignalR no está en el mismo dominio que la página de hospedaje), se usará WebSocket si se cumplen los siguientes criterios:

    • El cliente admite CORS (uso compartido de recursos entre orígenes). Para más información sobre qué clientes admiten CORS, consulte CORS en caniuse.com.

    • El cliente admite WebSocket.

    • El servidor admite WebSocket.

      Si no se cumple alguno de estos criterios, se usará el sondeo largo. Para obtener más información sobre las conexiones entre dominios, consulte Establecimiento de una conexión entre dominios.

  4. Si JSONP no está configurado y la conexión no es entre dominios, se usará WebSocket si tanto el cliente como el servidor lo admiten.

  5. Si el cliente o el servidor no admiten WebSocket, se usan eventos enviados por el servidor si está disponible.

  6. Si los eventos enviados por el servidor no están disponibles, se intenta Forever Frame.

  7. Si se produce un error en Forever Frame, se usa sondeo largo.

Supervisión de transportes

Puede determinar qué transporte usa la aplicación habilitando el registro en el centro y abriendo la ventana de consola en el explorador.

Para habilitar el registro de los eventos del centro en un explorador, agregue el siguiente comando a la aplicación cliente:

$.connection.hub.logging = true;

  • En Internet Explorer, abra las herramientas de desarrollo presionando F12 y haga clic en la pestaña Consola.

    Consola en Microsoft Internet Explorer

  • En Chrome, abra la consola presionando Ctrl+Mayús+J.

    Consola en Google Chrome

Con la consola abierta y el registro habilitado, podrá ver qué transporte usa SignalR.

Consola en Internet Explorer que muestra el transporte de WebSocket

Especificar un transporte

La negociación de un transporte tarda una cantidad determinada de tiempo y recursos de cliente/servidor. Si se conocen las funcionalidades del cliente, se puede especificar un transporte cuando se inicia la conexión de cliente. El siguiente fragmento de código muestra cómo iniciar una conexión mediante el transporte de sondeo largo de Ajax, como se usaría si se supiera que el cliente no admitía ningún otro protocolo:

connection.start({ transport: 'longPolling' });

Puede especificar un pedido de reserva si desea que un cliente pruebe transportes específicos en orden. En el siguiente fragmento de código se muestra cómo probar WebSocket y se produce un error, yendo directamente al sondeo largo.

connection.start({ transport: ['webSockets','longPolling'] });

Las constantes de cadena para especificar transportes se definen de la siguiente manera:

  • webSockets
  • foreverFrame
  • serverSentEvents
  • longPolling

Conexiones y centros de conectividad

La API de SignalR contiene dos modelos para comunicarse entre clientes y servidores: Conexiones persistentes y concentradores.

Una conexión representa un punto de conexión simple para enviar mensajes de un solo destinatario, agrupados o de difusión. La API de conexión persistente (representada en código .NET por la clase PersistentConnection) proporciona al desarrollador acceso directo al protocolo de comunicación de bajo nivel que Expone SignalR. El uso del modelo de comunicación Connections estará familiarizado con los desarrolladores que han usado API basadas en conexiones, como Windows Communication Foundation.

Un centro de conectividad es una canalización más de alto nivel basada en la API de conexión que permite al cliente y al servidor llamar directamente a métodos entre sí. SignalR controla el envío a través de los límites de la máquina como si fuera por magia, lo que permite a los clientes llamar a métodos en el servidor tan fácilmente como métodos locales, y viceversa. El uso del modelo de comunicación de Hubs estará familiarizado con los desarrolladores que han usado API de invocación remota, como .NET Remoting. El uso de un concentrador también permite pasar parámetros fuertemente tipados a métodos, lo que permite el enlace de modelos.

Diagrama de la arquitectura

En el diagrama siguiente se muestra la relación entre Hubs, Conexiones persistentes y las tecnologías subyacentes usadas para los transportes.

Diagrama de arquitectura de SignalR que muestra las API, los transportes y los clientes

Funcionamiento de Hubs

Cuando el código del lado servidor llama a un método en el cliente, se envía un paquete a través del transporte activo que contiene el nombre y los parámetros del método al que se va a llamar (cuando se envía un objeto como parámetro de método, se serializa mediante JSON). A continuación, el cliente coincide con el nombre del método con los métodos definidos en el código del lado cliente. Si hay una coincidencia, el método cliente se ejecutará mediante los datos de parámetros deserializados.

La llamada al método se puede supervisar mediante herramientas como Fiddler. En la imagen siguiente se muestra una llamada de método enviada desde un servidor signalR a un cliente de explorador web en el panel Registros de Fiddler. La llamada al método se envía desde un centro denominado MoveShapeHuby el método que se invoca se denomina updateShape.

Vista del registro de Fiddler que muestra el tráfico de SignalR

En este ejemplo, el nombre del concentrador se identifica con el H parámetro ; el nombre del método se identifica con el M parámetro y los datos que se envían al método se identifican con el A parámetro . La aplicación que generó este mensaje se crea en el tutorial de tiempo real de alta frecuencia .

Elección de un modelo de comunicación

La mayoría de las aplicaciones deben usar la API de Hubs. La API connections se puede usar en las siguientes circunstancias:

  • Es necesario especificar el formato del mensaje real enviado.
  • El desarrollador prefiere trabajar con un modelo de mensajería y distribución en lugar de un modelo de invocación remota.
  • Se está portado una aplicación existente que usa un modelo de mensajería para usar SignalR.