Solución de problemas de SignalR

de Patrick Fletcher

Advertencia

Esta documentación no es para la última versión de SignalR. Eche un vistazo a ASP.NET Core SignalR.

En este documento se describen los problemas comunes de solución de problemas con SignalR.

Versiones de software usadas en este tema

Versiones anteriores de este tema

Para obtener información sobre las versiones anteriores de SignalR, consulte Versiones anteriores de SignalR.

Preguntas y comentarios

Deje sus comentarios sobre cómo le gustó este tutorial y lo que podríamos mejorar en los comentarios en 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.

Este documento contiene las secciones siguientes.

Las llamadas a métodos entre el cliente y el servidor fallan silenciosamente.

En esta sección se describen las posibles causas de que se produzca un error en una llamada de método entre el cliente y el servidor sin un mensaje de error significativo. En una aplicación SignalR, el servidor no tiene información sobre los métodos que implementa el cliente; cuando el servidor invoca un método cliente, los datos de nombre y parámetro del método se envían al cliente y el método solo se ejecuta si existe en el formato especificado por el servidor. Si no se encuentra ningún método coincidente en el cliente, no ocurre nada y no se genera ningún mensaje de error en el servidor.

Para investigar más a fondo los métodos del cliente que no se están llamando, puede activar el registro antes de invocar el método start en el hub para ver qué llamadas provienen del servidor. Para habilitar el registro en una aplicación de JavaScript, consulte Habilitación del registro del lado cliente (versión de cliente de JavaScript). Para habilitar el registro en una aplicación cliente de .NET, consulte Habilitación del registro del lado cliente (versión de cliente .NET).

Método con errores de escritura, firma de método incorrecta o nombre de hub incorrecto

Si el nombre o la firma de un método llamado no coinciden exactamente con un método adecuado en el cliente, se producirá un error en la llamada. Compruebe que el nombre del método llamado por el servidor coincide con el nombre del método en el cliente. Además, SignalR crea el proxy del concentrador utilizando métodos en notación camel, como es adecuado en JavaScript; por lo tanto, un método llamado SendMessage en el servidor se llamaría sendMessage en el proxy del cliente. Si utiliza el atributo HubName en el código del lado del servidor, compruebe que el nombre coincida con el nombre utilizado para crear el concentrador en el cliente. Si no usa el atributo HubName, compruebe que el nombre del hub en un cliente de JavaScript está en notación camel, como chatHub en lugar de ChatHub.

Nombre de método duplicado en el cliente

Compruebe que no tiene un método duplicado en el cliente que solo difiere por mayúsculas y minúsculas. Si la aplicación cliente tiene un método denominado sendMessage, compruebe que tampoco hay un método llamado SendMessage .

Falta el analizador JSON en el cliente

SignalR requiere que un analizador JSON esté presente para serializar las llamadas entre el servidor y el cliente. Si el cliente no tiene un analizador JSON integrado (como Internet Explorer 7), deberá incluir uno en la aplicación. Puede descargar el analizador JSON aquí.

Combinación de la sintaxis Hub y PersistentConnection

SignalR usa dos modelos de comunicación: Hubs y PersistentConnections. La sintaxis para llamar a estos dos modelos de comunicación es diferente en el código de cliente. Si ha agregado un centro en el código de servidor, compruebe que todo el código de cliente usa la sintaxis del centro adecuada.

Código de cliente de JavaScript que crea un persistentConnection en un cliente de JavaScript

var myConnection = $.connection('/echo');

Código de cliente de JavaScript que crea un Hub Proxy en un cliente JavaScript

var myHub = $.connection.MyHub;

Código de servidor de C# que asigna una ruta a persistentConnection

RouteTable.Routes.MapConnection<MyConnection>("my", "/echo");

Código de servidor de C# que asigna una ruta a un centro o a varios centros si tiene varias aplicaciones

App.MapSignalR();

Conexión iniciada antes de agregar suscripciones

Si la conexión del concentrador se inicia antes de que se agreguen los métodos a los que se puede llamar desde el servidor al proxy, no se recibirán mensajes. El código JavaScript siguiente no iniciará correctamente el centro:

Código de cliente javaScript incorrecto que no permitirá que se reciban mensajes de Hubs

var chat = $.connection.chatHub;
$.connection.hub.start().done(function () {
    chat.client.broadcastMessage = function (name, message) {...};
});

En su lugar, agregue las suscripciones de método antes de llamar a Start:

Código de cliente de JavaScript que agrega correctamente suscripciones a un centro

var chat = $.connection.chatHub;
chat.client.broadcastMessage = function (name, message) {...};
    $.connection.hub.start().done(function () {
        ...
    });

Falta el nombre del método en el proxy del centro

Compruebe que el método definido en el servidor está suscrito a en el cliente. Aunque el servidor define el método , todavía debe agregarse al proxy de cliente. Los métodos se pueden agregar al proxy del cliente de las maneras siguientes (tenga en cuenta que el método se agrega al miembro client del hub, no al hub directamente):

Código de cliente de JavaScript que agrega métodos a un proxy de concentrador

// Method added to proxy in JavaScript:
myHubProxy.server.method1 = function (param1, param2) {...};
//Multiple methods added to proxy in JavaScript using jQuery:
$.extend(myHubProxy.server, {
    method1: function (param1, param2) {...},
    method2: function (param3, param4) {...}
});

Métodos de hub o hubs no declarados como públicos

Para que sea visible en el cliente, la implementación y los métodos del centro deben declararse como public.

Acceso al centro desde una aplicación diferente

Solo se puede acceder a SignalR Hubs a través de aplicaciones que implementan clientes de SignalR. SignalR no puede interoperar con otras bibliotecas de comunicación (como servicios web SOAP o WCF). Si no hay ningún cliente signalR disponible para la plataforma de destino, no podrá acceder directamente al punto de conexión del servidor.

Serialización manual de datos

SignalR usará automáticamente JSON para serializar los parámetros del método; no es necesario hacerlo usted mismo.

Método del centro de conectividad remoto no ejecutado en el cliente en la función OnDisconnected

Este comportamiento se debe al diseño. Cuando se llama a OnDisconnected, el hub ya ha entrado en el estado Disconnected, el cual no permite llamar a métodos adicionales del hub.

Código de servidor de C# que ejecuta correctamente el código en el evento OnDisconnected

public class MyHub : Hub
{
    public override Task OnDisconnected()
    {
        // Do what you want here
        return base.OnDisconnected();
    }
}

OnDisconnect no se activa en momentos coherentes

Este comportamiento se debe al diseño. Cuando un usuario intenta alejarse de una página con una conexión de SignalR activa, el cliente de SignalR realizará un mejor intento de notificar al servidor que se detendrá la conexión de cliente. Si el intento de mejor esfuerzo del cliente de SignalR no puede llegar al servidor, el servidor eliminará la conexión después de un periodo configurable DisconnectTimeout, momento en el que se desencadenará el evento OnDisconnected. Si el intento del cliente de SignalR de realizar el mejor esfuerzo tiene éxito, el evento OnDisconnected se desencadenará inmediatamente.

Para obtener información sobre cómo establecer la DisconnectTimeout configuración, consulte Control de eventos de duración de conexión: DisconnectTimeout.

Límite de conexión alcanzado

Cuando se usa la versión completa de IIS en un sistema operativo cliente como Windows 7, se impone un límite de conexión de 10. Al usar un sistema operativo cliente, use IIS Express en su lugar para evitar este límite.

Conexión entre dominios no configurada correctamente

Si una conexión entre dominios (una conexión para la que la dirección URL de SignalR no está en el mismo dominio que la página de hospedaje) no está configurada correctamente, es posible que se produzca un error en la conexión sin un mensaje de error. Para obtener información sobre cómo habilitar la comunicación entre dominios, vea Cómo establecer una conexión entre dominios.

La conexión mediante NTLM (Active Directory) no funciona en el cliente de .NET

Es posible que se produzca un error en una conexión en una aplicación cliente de .NET que use Seguridad de dominio si la conexión no está configurada correctamente. Para usar SignalR en un entorno de dominio, establezca la propiedad de conexión necesaria de la siguiente manera:

Código de cliente de C# que implementa credenciales de conexión

connection.Credentials = CredentialCache.DefaultCredentials;

Configuración de WebSockets de IIS para realizar ping/pong y detectar un cliente inactivo

Los servidores de SignalR no saben si el cliente está muerto o no, y dependen de la notificación del websocket subyacente para detectar fallos de conexión, es decir, la OnClose devolución de llamada. Una solución a este problema es configurar websockets de IIS para hacer el ping/pong para usted. Esto garantiza que la conexión se cerrará si se interrumpe inesperadamente. Para obtener más información, consulte esta publicación de stackoverflow.

Otros problemas de conexión

En esta sección se describen las causas y soluciones de síntomas específicos o mensajes de error que se producen durante una conexión.

Error "Debe llamarse a Start antes de que se puedan enviar los datos"

Este error se suele ver si el código hace referencia a objetos SignalR antes de iniciar la conexión. La configuración para controladores y similares que llamará a los métodos definidos en el servidor debe agregarse después de que se complete la conexión. Tenga en cuenta que la llamada a Start es asincrónica, por lo que el código después de la llamada se puede ejecutar antes de que se complete. La mejor manera de agregar manejadores una vez que la conexión se ha iniciado por completo es colocarlos en una función de devolución de llamada, pasándolos como parámetros al método start.

Código de cliente de JavaScript que agrega correctamente controladores de eventos que hacen referencia a objetos SignalR

$.connection.hub.start().done(function () {
    // Wire up Send button to call NewContosoChatMessage on the server.
    $('#newContosoChatMessage').click(function () {
        contosoChatHubProxy.server.newContosoChatMessage(
            $('#displayname').val(), $('#message').val());
            $('#message').val('').focus();
    });

Este error también se verá si se detiene una conexión mientras se sigue haciendo referencia a los objetos SignalR.

Error "301 Movido permanentemente" o "302 Movido temporalmente"

Este error puede verse si el proyecto contiene una carpeta denominada SignalR, que interferirá con el proxy creado automáticamente. Para evitar este error, no use una carpeta denominada SignalR en la aplicación o desactive la generación automática de proxy. Consulte El proxy generado y lo que hace para usted para más detalles.

Error "403 Prohibido" en el cliente de .NET o Silverlight

Este error puede producirse en entornos entre dominios en los que la comunicación entre dominios no está habilitada correctamente. Para obtener información sobre cómo habilitar la comunicación entre dominios, vea Cómo establecer una conexión entre dominios. Para establecer una conexión entre dominios en un cliente de Silverlight, consulte Conexiones entre dominios de clientes de Silverlight.

Error "404 No encontrado"

Hay varias causas de este problema. Compruebe lo siguiente:

  • Referencia de la dirección proxy del concentrador con formato incorrecto: Este error se suele ver si la referencia a la dirección proxy del concentrador generada no tiene el formato correcto. Compruebe que la referencia a la dirección del centro se realiza correctamente. Consulte Cómo hacer referencia al proxy generado dinámicamente para obtener más información.

  • Agregar rutas a la aplicación antes de agregar la ruta del concentrador: Si la aplicación usa otras rutas, compruebe que la primera ruta agregada es la llamada a MapSignalR.

  • Usar IIS 7 o 7.5 sin la actualización para direcciones URL sin extensión: Requiere una actualización de las direcciones URL sin extensión para que el servidor pueda proporcionar acceso a las definiciones del concentrador en /signalr/hubs. La actualización se puede encontrar aquí.

  • Caché de IIS obsoleta o dañada: Para comprobar que el contenido de la memoria caché no está actualizado, escriba el siguiente comando en una ventana de PowerShell para borrar la memoria caché:

    net stop w3svc
    Remove-Item -Path "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\*" -Force -Recurse
    net start w3svc
    

"Error interno del servidor 500"

Se trata de un error muy genérico que podría tener una amplia variedad de causas. Los detalles del error deben aparecer en el registro de eventos del servidor o se pueden encontrar a través de la depuración del servidor. Para obtener información más detallada sobre errores, active la opción de errores detallados en el servidor. Para obtener más información, consulte Control de errores en la clase Hub.

Este error también se ve normalmente si un firewall o proxy no está configurado correctamente, lo que provoca que los encabezados de solicitud se vuelvan a escribir. La solución consiste en asegurarse de que el puerto 80 está habilitado en el firewall o el proxy.

"Código de respuesta inesperado: 500"

Este error puede producirse si la versión de .NET Framework usada en la aplicación no coincide con la versión especificada en Web.Config. La solución consiste en comprobar que .NET 4.5 se usa en la configuración de la aplicación y en el archivo Web.Config.

Error de "TypeError: <hubType> is undefined"

Este error se producirá si la llamada a MapSignalR no se realiza correctamente. Consulte Registro del middleware de SignalR y configuración de las opciones de SignalR para obtener más información.

JsonSerializationException no fue manejada por el código de usuario

Compruebe que los parámetros que envíe a los métodos no incluyen tipos no serializables (como identificadores de archivo o conexiones de base de datos). Si necesita usar miembros en un objeto del lado servidor que no desea enviar al cliente (ya sea por seguridad o por motivos de serialización), use el JSONIgnore atributo .

Error de protocolo: transporte desconocido

Este error puede producirse si el cliente no admite los transportes que usa SignalR. Consulte Transports and Fallbacks (Transportes y Alternativas) para obtener información sobre qué navegadores se pueden usar con SignalR.

Se ha deshabilitado la generación de proxy del Hub de JavaScript.

Este error se producirá si DisableJavaScriptProxies se establece mientras también se incluye una referencia al proxy generado dinámicamente en signalr/hubs. Para obtener más información sobre cómo crear el proxy manualmente, consulte El proxy generado y lo que hace por usted.

"El identificador de conexión está en el formato incorrecto" o "La identidad del usuario no puede cambiar durante una conexión de SignalR activa"

Este error puede ocurrir si se está usando la autenticación y se ha cerrado la sesión del cliente antes de que se interrumpa la conexión. La solución consiste en detener la conexión de SignalR antes de cerrar el cliente.

"Error no detectado: SignalR: jQuery no encontrado. Asegúrese de que se hace referencia a jQuery antes del archivo SignalR.js.

El cliente javaScript de SignalR requiere que se ejecute jQuery. Compruebe que la referencia a jQuery es correcta, que la ruta de acceso usada es válida y que la referencia a jQuery es anterior a la referencia a SignalR.

Error "Uncaught TypeError: No se puede leer la propiedad '<property>' de 'indefinido'"

Este error resulta de no hacer referencia correctamente a jQuery o al proxy de concentradores. Compruebe que las referencias a jQuery y al proxy de concentradores son correctas, que la ruta de acceso usada es válida y que la referencia a jQuery es antes de la referencia del proxy de concentradores. La referencia predeterminada al proxy de hubs debe ser similar a la siguiente:

Código del lado cliente HTML que hace referencia correctamente al proxy de Hubs

<script src="/signalr/hubs"></script>

Error "RuntimeBinderException no se ha controlado mediante el código de usuario".

Este error puede producirse cuando se usa la sobrecarga incorrecta de Hub.On . Si el método tiene un valor devuelto, el tipo de valor devuelto debe especificarse como parámetro de tipo genérico:

Método definido en el cliente (sin proxy generado)

MyHub.On<ReturnType>("MethodName", LocalMethod);

Identificador de conexión inconsistente o la conexión se interrumpe entre cargas de página

Este comportamiento se debe al diseño. Dado que el objeto de concentrador se hospeda en el objeto de página, el centro se destruye cuando se actualiza la página. Una aplicación de varias páginas debe mantener la asociación entre los usuarios y los identificadores de conexión para que sean coherentes entre las cargas de página. Los identificadores de conexión se pueden almacenar en el servidor en un ConcurrentDictionary objeto o en una base de datos.

Error "El valor no puede ser null"

Actualmente no se admiten métodos del lado servidor con parámetros opcionales; Si se omite el parámetro opcional, se producirá un error en el método. Para obtener más información, vea Parámetros opcionales.

Error "Firefox no puede establecer una conexión con el servidor en <la dirección>" en Firebug

Este mensaje de error se puede ver en Firebug si se produce un error en la negociación del transporte de WebSocket y se usa otro transporte en su lugar. Este comportamiento se debe al diseño.

Error "El certificado remoto no es válido según el procedimiento de validación" en la aplicación cliente de .NET

Si el servidor requiere certificados de cliente personalizados, puede agregar un certificado x509 a la conexión antes de realizar la solicitud. Agregue el certificado a la conexión mediante Connection.AddClientCertificate.

Se pierde la conexión después de que se agote el tiempo de espera de la autenticación.

Este comportamiento se debe al diseño. Las credenciales de autenticación no se pueden modificar mientras una conexión está activa; para actualizar las credenciales, la conexión debe detenerse y reiniciarse.

Se llama a OnConnected dos veces al usar jQuery Mobile

La función de initializePage jQuery Mobile obliga a que los scripts de cada página se vuelvan a ejecutar, lo que crea una segunda conexión. Entre las soluciones para este problema se incluyen:

  • Incluya la referencia a jQuery Mobile antes del archivo JavaScript.
  • Deshabilite la initializePage función estableciendo $.mobile.autoInitializePage = false.
  • Espere a que la página termine de inicializarse antes de iniciar la conexión.

Los mensajes se retrasan en las aplicaciones de Silverlight mediante eventos enviados por el servidor

Los mensajes se retrasan al usar eventos enviados por el servidor en Silverlight. Para forzar que se utilice el sondeo prolongado en su lugar, use lo siguiente al iniciar la conexión:

connection.Start(new LongPollingTransport());

"Permiso denegado" mediante el protocolo Forever Frame

Se trata de un problema conocido, que se describe aquí. Este síntoma puede verse usando la biblioteca JQuery más reciente; la solución consiste en degradar la aplicación a JQuery 1.8.2.

"InvalidOperationException: no es una solicitud de socket web válida.

Este error puede producirse si se usa el protocolo WebSocket, pero el proxy de red está modificando los encabezados de solicitud. La solución consiste en configurar el proxy para permitir WebSocket en el puerto 80.

Excepción: <el nombre del método> no se pudo resolver cuando el cliente llama al método en el servidor

Este error puede deberse al uso de tipos de datos que no se pueden detectar en una carga JSON, como Array. La solución alternativa es usar un tipo de datos reconocible por JSON, como IList. Para obtener más información, vea Cliente .NET no puede llamar a métodos de concentrador con parámetros de matriz.

Errores de compilación y del lado del servidor

En la sección siguiente se incluyen posibles soluciones para los errores en tiempo de ejecución del compilador y del lado servidor.

La referencia a la instancia de Hub es null

Dado que se crea una instancia de concentrador para cada conexión, no puede crear una instancia de un concentrador en su propio código. Para llamar a métodos en un centro desde fuera del propio centro, consulte Cómo llamar a métodos de cliente y administrar grupos desde fuera de la clase Hub para obtener una referencia al contexto del centro.

HTTPContext.Current.Session es null

Este comportamiento se debe al diseño. SignalR no admite el estado de sesión de ASP.NET, ya que habilitar el estado de sesión interrumpiría la mensajería dúplex.

No hay ningún método adecuado para invalidar

Es posible que vea este error si usa código de documentación o blogs anteriores. Compruebe que no hace referencia a nombres de métodos que se han cambiado o en desuso (como OnConnectedAsync).

HostContextExtensions.WebSocketServerUrl es null

Este comportamiento se debe al diseño. Este miembro está en desuso y no debe usarse.

Ya existe una ruta llamada "signalr.hubs" en la colección de rutas.

Este error ocurrirá si la aplicación llama a MapSignalR dos veces. Algunas aplicaciones de ejemplo llaman MapSignalR directamente en la clase Startup; otras realizan la llamada en una clase contenedora. Asegúrese de que la aplicación no haga ambas acciones.

WebSocket no se usa

Si ha comprobado que el servidor y los clientes cumplen los requisitos de WebSocket (enumerados en el documento Plataformas admitidas ), deberá habilitar WebSocket en el servidor. Puede encontrar instrucciones para hacerlo aquí.

$.connection no está definido

Este error indica que los scripts de una página no se cargan correctamente, o que el proxy del centro no es accesible o al que se accede incorrectamente. Compruebe que las referencias de script de la página corresponden a los scripts cargados en el proyecto y que se puede tener acceso a /signalr/hubs en un explorador cuando se ejecuta el servidor.

No se pueden encontrar uno o varios tipos necesarios para compilar una expresión dinámica.

Este error indica que falta la Microsoft.CSharp biblioteca. Agréguelo en la pestaña Ensamblados-Framework>.

No se puede acceder al estado del llamador desde Clients.Caller en Visual Basic o en un concentrador fuertemente tipado; error "La conversión del tipo 'Task(Of Object)' al tipo 'String' no es válida"

Para acceder al estado del llamador en Visual Basic o en un concentrador fuertemente tipado, use la propiedad Clients.CallerState (introducida en SignalR 2.1) en lugar de Clients.Caller.

Problemas de Visual Studio

En esta sección se describen los problemas detectados en Visual Studio.

El nodo Documentos de script no aparece en el Explorador de soluciones

Algunos de nuestros tutoriales le dirigen al nodo "Script Documents" en el Explorador de soluciones durante la depuración. El depurador de JavaScript genera este nodo y solo aparecerá durante la depuración de clientes del explorador en Internet Explorer; El nodo no aparecerá si se usa Chrome o Firefox. El depurador de JavaScript tampoco se ejecutará si se está ejecutando otro depurador de cliente, como el depurador de Silverlight.

SignalR no funciona en Visual Studio 2008 ni en versiones anteriores

Este comportamiento se debe al diseño. SignalR requiere .NET Framework 4 o posterior; esto requiere que las aplicaciones signalR se desarrollen en Visual Studio 2010 o posterior. El componente de servidor de SignalR requiere .NET Framework 4.5.

Problemas de IIS

Esta sección contiene problemas con Internet Information Services.

SignalR funciona en el servidor de desarrollo de Visual Studio, pero no en IIS

SignalR se admite en IIS 7.0 y 7.5, pero se debe agregar compatibilidad con direcciones URL sin extensión. Para agregar compatibilidad con direcciones URL sin extensiones, consulte https://support.microsoft.com/kb/980368

SignalR requiere ASP.NET instalarse en el servidor (ASP.NET no está instalado en IIS de forma predeterminada). Para instalar ASP.NET, consulte descargas de ASP.NET.

Problemas de Microsoft Azure

Esta sección contiene problemas con Microsoft Azure.

FileLoadException al hospedar SignalR en un rol de trabajo de Azure

Hospedar SignalR en un rol de trabajo de Azure podría dar lugar a la excepción "No se pudo cargar el archivo o ensamblado "Microsoft.Owin, Version=2.0.0.0". Se trata de un problema conocido con NuGet; Las redirecciones de enlace no se agregan automáticamente en los proyectos de rol de trabajo de Azure. Para corregirlo, puede agregar las redirecciones de enlace manualmente. Agregue las líneas siguientes al archivo app.config de su proyecto de rol de trabajo.

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.2.0" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.2.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Los mensajes no se reciben a través del backplane de Azure después de modificar los nombres de temas

Los temas usados por el backplane de Azure se mantienen internamente; no están diseñados para ser configurables por el usuario.