Compartilhar via


Solução de problemas do SignalR

por Patrick Fletcher

Aviso

Esta documentação não é para a versão mais recente do SignalR. Dê uma olhada em ASP.NET Core SignalR.

Este documento descreve problemas comuns de solução de problemas com o SignalR.

Versões de software usadas neste tópico

Versões anteriores deste tópico

Para obter informações sobre versões anteriores do SignalR, consulte Versões mais antigas do SignalR.

Perguntas e comentários

Deixe comentários sobre como você gostou deste tutorial e o que poderíamos melhorar nos comentários na parte inferior da página. Se você tiver dúvidas que não estão diretamente relacionadas ao tutorial, poderá postá-las no fórum do ASP.NET SignalR ou StackOverflow.com.

Este documento contém as seções a seguir.

Os métodos de chamada entre o cliente e o servidor falham silenciosamente

Esta seção descreve as possíveis causas para uma chamada de método entre o cliente e o servidor falharem sem uma mensagem de erro significativa. Em um aplicativo SignalR, o servidor não tem informações sobre os métodos que o cliente implementa; quando o servidor invoca um método de cliente, o nome do método e os dados de parâmetro são enviados para o cliente e o método é executado somente se ele existir no formato especificado pelo servidor. Se nenhum método correspondente for encontrado no cliente, nada acontecerá e nenhuma mensagem de erro será gerada no servidor.

Para investigar ainda mais os métodos de cliente que não estão sendo chamados, você pode ativar o registro em log antes de chamar o método start no hub para ver quais chamadas vêm do servidor. Para habilitar o registro em log em um aplicativo JavaScript, consulte Como habilitar o log do lado do cliente (versão do cliente JavaScript). Para habilitar o registro em log em um aplicativo cliente .NET, consulte Como habilitar o log do lado do cliente (versão do cliente .NET).

Método com ortografia incorreta, assinatura de método incorreta ou nome incorreto do hub

Se o nome ou a assinatura de um método chamado não corresponder exatamente a um método apropriado no cliente, a chamada falhará. Verifique se o nome do método chamado pelo servidor corresponde ao nome do método no cliente. Além disso, o SignalR cria o proxy de hub usando métodos com maiúsculas e minúsculas, como é apropriado em JavaScript, portanto, um método chamado SendMessage no servidor seria chamado sendMessage no proxy do cliente. Se você usar o HubName atributo no código do lado do servidor, verifique se o nome usado corresponde ao nome usado para criar o hub no cliente. Se você não usar o HubName atributo , verifique se o nome do hub em um cliente JavaScript tem maiúsculas e minúsculas, como chatHub em vez de ChatHub.

Nome do método duplicado no cliente

Verifique se você não tem um método duplicado no cliente que difere apenas por caso. Se o aplicativo cliente tiver um método chamado sendMessage, verifique se também não há um método chamado SendMessage .

Analisador JSON ausente no cliente

O SignalR requer que um analisador JSON esteja presente para serializar chamadas entre o servidor e o cliente. Se o cliente não tiver um analisador JSON interno (como Internet Explorer 7), você precisará incluir um em seu aplicativo. Você pode baixar o analisador JSON aqui.

Sintaxe de Hub de Combinação e PersistentConnection

O SignalR usa dois modelos de comunicação: Hubs e PersistentConnections. A sintaxe para chamar esses dois modelos de comunicação é diferente no código do cliente. Se você adicionou um hub no código do servidor, verifique se todo o código do cliente usa a sintaxe de hub adequada.

Código do cliente JavaScript que cria um PersistentConnection em um cliente JavaScript

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

Código do cliente JavaScript que cria um Proxy de Hub em um cliente Javascript

var myHub = $.connection.MyHub;

Código do servidor C# que mapeia uma rota para um PersistentConnection

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

Código do servidor C# que mapeia uma rota para um Hub ou para vários hubs se você tiver vários aplicativos

App.MapSignalR();

Conexão iniciada antes que as assinaturas sejam adicionadas

Se a conexão do Hub for iniciada antes que os métodos que podem ser chamados do servidor sejam adicionados ao proxy, as mensagens não serão recebidas. O código JavaScript a seguir não iniciará o hub corretamente:

Código de cliente JavaScript incorreto que não permitirá que mensagens de Hubs sejam recebidas

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

Em vez disso, adicione as assinaturas de método antes de chamar Iniciar:

Código do cliente JavaScript que adiciona corretamente assinaturas a um hub

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

Nome do método ausente no proxy do hub

Verifique se o método definido no servidor está inscrito no cliente. Embora o servidor defina o método , ele ainda deve ser adicionado ao proxy do cliente. Os métodos podem ser adicionados ao proxy do cliente das seguintes maneiras (observe que o método é adicionado ao client membro do hub, não ao hub diretamente):

Código do cliente JavaScript que adiciona métodos a um proxy de hub

// 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 ou hub não declarados como Públicos

Para ficar visível no cliente, a implementação e os métodos do hub devem ser declarados como public.

Acessando o hub de um aplicativo diferente

Os Hubs do SignalR só podem ser acessados por meio de aplicativos que implementam clientes signalR. O SignalR não pode interoperar com outras bibliotecas de comunicação (como soap ou serviços Web WCF.) Se não houver nenhum cliente signalR disponível para sua plataforma de destino, você não poderá acessar o ponto de extremidade do servidor diretamente.

Serializando dados manualmente

O SignalR usará automaticamente o JSON para serializar os parâmetros do método. Não há necessidade de fazer isso por conta própria.

Método de Hub Remoto não executado no cliente na função OnDisconnected

Este comportamento ocorre por design. Quando OnDisconnected é chamado, o hub já entrou no Disconnected estado , que não permite que outros métodos de hub sejam chamados.

Código do servidor C# que executa corretamente o código no evento OnDisconnected

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

OnDisconnect não é disparado em momentos consistentes

Este comportamento ocorre por design. Quando um usuário tenta sair de uma página com uma conexão do SignalR ativa, o cliente signalR fará uma tentativa de melhor esforço para notificar o servidor de que a conexão do cliente será interrompida. Se a tentativa de melhor esforço do cliente do SignalR não conseguir alcançar o servidor, o servidor descartará a conexão após um configurável DisconnectTimeout posteriormente, momento em que o OnDisconnected evento será acionado. Se a tentativa de melhor esforço do cliente do SignalR for bem-sucedida, o OnDisconnected evento será acionado imediatamente.

Para obter informações sobre como definir a DisconnectTimeout configuração, consulte Manipulando eventos de tempo de vida da conexão: DisconnectTimeout.

Limite de conexão atingido

Ao usar a versão completa do IIS em um sistema operacional cliente como o Windows 7, um limite de 10 conexões é imposto. Ao usar um sistema operacional cliente, use IIS Express para evitar esse limite.

A conexão entre domínios não está configurada corretamente

Se uma conexão entre domínios (uma conexão para a qual a URL do SignalR não está no mesmo domínio que a página de hospedagem) não estiver configurada corretamente, a conexão poderá falhar sem uma mensagem de erro. Para obter informações sobre como habilitar a comunicação entre domínios, consulte Como estabelecer uma conexão entre domínios.

A conexão usando o NTLM (Active Directory) não está funcionando no cliente .NET

Uma conexão em um aplicativo cliente .NET que usa a segurança de domínio poderá falhar se a conexão não estiver configurada corretamente. Para usar o SignalR em um ambiente de domínio, defina a propriedade de conexão necessária da seguinte maneira:

Código do cliente C# que implementa credenciais de conexão

connection.Credentials = CredentialCache.DefaultCredentials;

Configurando websockets do IIS para ping/pong para detectar um cliente morto

Os servidores SignalR não sabem se o cliente está morto ou não e dependem da notificação do websocket subjacente para falhas de conexão, ou seja, o OnClose retorno de chamada. Uma solução para esse problema é configurar websockets do IIS para fazer o ping/pong para você. Isso garante que sua conexão será fechada se ela for interrompida inesperadamente. Para obter mais informações, consulte esta postagem de stackoverflow.

Outros problemas de conexão

Esta seção descreve as causas e soluções para sintomas específicos ou mensagens de erro que ocorrem durante uma conexão.

Erro "Iniciar deve ser chamado antes que os dados possam ser enviados"

Esse erro geralmente é visto se o código faz referência a objetos SignalR antes da conexão ser iniciada. A transmissão para manipuladores e similares que chamarão métodos definidos no servidor deve ser adicionada após a conclusão da conexão. Observe que a chamada para Start é assíncrona, portanto, o código após a chamada pode ser executado antes de ser concluída. A melhor maneira de adicionar manipuladores depois que uma conexão é iniciada completamente é colocá-los em uma função de retorno de chamada que é passada como um parâmetro para o método start:

Código do cliente JavaScript que adiciona corretamente manipuladores de eventos que fazem referência 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();
    });

Esse erro também será visto se uma conexão for interrompida enquanto os objetos SignalR ainda estiverem sendo referenciados.

Erro "301 movido permanentemente" ou "302 movido temporariamente"

Esse erro poderá ser visto se o projeto contiver uma pasta chamada SignalR, que interferirá no proxy criado automaticamente. Para evitar esse erro, não use uma pasta chamada SignalR em seu aplicativo ou desative a geração automática de proxy. Consulte o Proxy Gerado e o que ele faz para você para obter mais detalhes.

Erro "403 Proibido" no cliente .NET ou Silverlight

Esse erro pode ocorrer em ambientes entre domínios em que a comunicação entre domínios não está habilitada corretamente. Para obter informações sobre como habilitar a comunicação entre domínios, consulte Como estabelecer uma conexão entre domínios. Para estabelecer uma conexão entre domínios em um cliente Silverlight, consulte Conexões entre domínios de clientes do Silverlight.

Erro "404 Não Encontrado"

Há várias causas para esse problema. Verifique todas as seguintes opções:

  • Referência de endereço proxy do hub não formatada corretamente: Esse erro geralmente é visto se a referência ao endereço proxy do hub gerado não está formatada corretamente. Verifique se a referência ao endereço do hub foi feita corretamente. Consulte Como fazer referência ao proxy gerado dinamicamente para obter detalhes.

  • Adicionando rotas ao aplicativo antes de adicionar a rota do hub: Se o aplicativo usar outras rotas, verifique se a primeira rota adicionada é a chamada para MapSignalR.

  • Usando o IIS 7 ou 7.5 sem a atualização para URLs sem extensão: O uso do IIS 7 ou 7.5 requer uma atualização para URLs sem extensão para que o servidor possa fornecer acesso às definições do hub em /signalr/hubs. A atualização pode ser encontrada aqui.

  • Cache do IIS desatualizado ou corrompido: Para verificar se o conteúdo do cache não está desatualizado, insira o seguinte comando em uma janela do PowerShell para limpar o cache:

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

"Erro de servidor interno 500"

Esse é um erro muito genérico que pode ter uma ampla variedade de causas. Os detalhes do erro devem aparecer no log de eventos do servidor ou podem ser encontrados por meio da depuração do servidor. Informações de erro mais detalhadas podem ser obtidas ativando erros detalhados no servidor. Para obter mais informações, consulte Como lidar com erros na classe Hub.

Esse erro também é comumente visto se um firewall ou proxy não está configurado corretamente, fazendo com que os cabeçalhos de solicitação sejam reescritos. A solução é garantir que a porta 80 esteja habilitada no firewall ou proxy.

"Código de resposta inesperado: 500"

Esse erro poderá ocorrer se a versão do .NET Framework usada no aplicativo não corresponder à versão especificada em Web.Config. A solução é verificar se o .NET 4.5 é usado nas configurações do aplicativo e no arquivo Web.Config.

Erro "TypeError: <hubType> é indefinido"

Esse erro resultará se a chamada para MapSignalR não for feita corretamente. Confira Como registrar o Middleware do SignalR e configurar as opções do SignalR para obter mais informações.

JsonSerializationException foi sem tratamento pelo código do usuário

Verifique se os parâmetros enviados para seus métodos não incluem tipos não serializáveis (como identificadores de arquivo ou conexões de banco de dados). Se você precisar usar membros em um objeto do lado do servidor que não deseja ser enviado ao cliente (por segurança ou por motivos de serialização), use o JSONIgnore atributo .

Erro de "Protocolo: transporte desconhecido"

Esse erro poderá ocorrer se o cliente não der suporte aos transportes que o SignalR usa. Consulte Transportes e Fallbacks para obter informações sobre quais navegadores podem ser usados com o SignalR.

"A geração de proxy do Hub JavaScript foi desabilitada."

Esse erro ocorrerá se DisableJavaScriptProxies estiver definido, incluindo também uma referência ao proxy gerado dinamicamente em signalr/hubs. Para obter mais informações sobre como criar o proxy manualmente, consulte O proxy gerado e o que ele faz por você.

Erro "A ID de conexão está no formato incorreto" ou "A identidade do usuário não pode ser alterada durante uma conexão do SignalR ativa"

Esse erro poderá ser visto se a autenticação estiver sendo usada e o cliente estiver conectado antes que a conexão seja interrompida. A solução é interromper a conexão do SignalR antes de fazer logoff do cliente.

"Erro descaso: SignalR: jQuery não encontrado. Verifique se jQuery é referenciado antes do erro SignalR.js arquivo"

O cliente JavaScript do SignalR requer que jQuery seja executado. Verifique se a referência a jQuery está correta, se o caminho usado é válido e se a referência a jQuery está antes da referência ao SignalR.

Erro "TypeError uncaught: não é possível ler a propriedade '<property>' de indefinido"

Esse erro resulta de não ter jQuery ou o proxy de hubs referenciado corretamente. Verifique se sua referência ao jQuery e ao proxy de hubs está correta, se o caminho usado é válido e se a referência a jQuery está antes da referência ao proxy de hubs. A referência padrão ao proxy de hubs deve ser semelhante à seguinte:

Código do lado do cliente HTML que faz referência correta ao proxy hubs

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

Erro "RuntimeBinderException foi sem tratamento pelo código do usuário"

Esse erro pode ocorrer quando a sobrecarga incorreta de Hub.On é usada. Se o método tiver um valor retornado, o tipo de retorno deverá ser especificado como um parâmetro de tipo genérico:

Método definido no cliente (sem proxy gerado)

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

A ID de conexão é inconsistente ou quebras de conexão entre cargas de página

Este comportamento ocorre por design. Como o objeto hub está hospedado no objeto de página, o hub é destruído quando a página é atualizada. Um aplicativo de várias páginas precisa manter a associação entre usuários e IDs de conexão para que eles sejam consistentes entre cargas de página. As IDs de conexão podem ser armazenadas no servidor em um ConcurrentDictionary objeto ou em um banco de dados.

Erro "Valor não pode ser nulo"

Atualmente, não há suporte para métodos do lado do servidor com parâmetros opcionais; se o parâmetro opcional for omitido, o método falhará. Para obter mais informações, confira Parâmetros opcionais.

Erro "O Firefox não pode estabelecer uma conexão com o servidor no <endereço>" no Firebug

Essa mensagem de erro poderá ser vista no Firebug se a negociação do transporte WebSocket falhar e outro transporte for usado. Este comportamento ocorre por design.

Erro "O certificado remoto é inválido de acordo com o procedimento de validação" no aplicativo cliente .NET

Se o servidor exigir certificados de cliente personalizados, você poderá adicionar um x509certificate à conexão antes que a solicitação seja feita. Adicione o certificado à conexão usando Connection.AddClientCertificate.

A conexão cai após o tempo limite da autenticação

Este comportamento ocorre por design. As credenciais de autenticação não podem ser modificadas enquanto uma conexão está ativa; para atualizar as credenciais, a conexão deve ser interrompida e reiniciada.

OnConnected é chamado duas vezes ao usar jQuery Mobile

A função do initializePage jQuery Mobile força os scripts em cada página a serem executados novamente, criando assim uma segunda conexão. As soluções para esse problema incluem:

  • Inclua a referência ao jQuery Mobile antes do arquivo JavaScript.
  • Desabilite a initializePage função definindo $.mobile.autoInitializePage = false.
  • Aguarde até que a página termine de inicializar antes de iniciar a conexão.

As mensagens são atrasadas em aplicativos Silverlight usando eventos enviados pelo servidor

As mensagens são atrasadas ao usar eventos enviados pelo servidor no Silverlight. Para forçar a sondagem longa a ser usada, use o seguinte ao iniciar a conexão:

connection.Start(new LongPollingTransport());

"Permissão negada" usando o protocolo Forever Frame

Esse é um problema conhecido, descrito aqui. Esse sintoma pode ser visto usando a biblioteca JQuery mais recente; a solução alternativa é fazer downgrade do aplicativo para o JQuery 1.8.2.

"InvalidOperationException: não é uma solicitação de soquete da Web válida.

Esse erro poderá ocorrer se o protocolo WebSocket for usado, mas o proxy de rede estiver modificando os cabeçalhos de solicitação. A solução é configurar o proxy para permitir o WebSocket na porta 80.

"Exceção: <método de nome> de método não pôde ser resolvido" quando o cliente chama o método no servidor

Esse erro pode resultar do uso de tipos de dados que não podem ser descobertos em uma carga JSON, como Array. A solução alternativa é usar um tipo de dados detectável por JSON, como IList. Para obter mais informações, consulte Cliente .NET não é capaz de chamar métodos de hub com parâmetros de matriz.

Erros de compilação e do lado do servidor

A seção a seguir contém possíveis soluções para erros de runtime do compilador e do lado do servidor.

A referência à instância do Hub é nula

Como uma instância de hub é criada para cada conexão, você não pode criar uma instância de um hub em seu código por conta própria. Para chamar métodos em um hub de fora do próprio hub, consulte Como chamar métodos de cliente e gerenciar grupos de fora da classe Hub para saber como obter uma referência ao contexto do hub.

HTTPContext.Current.Session é nulo

Este comportamento ocorre por design. O SignalR não dá suporte ao estado de sessão ASP.NET, pois habilitar o estado da sessão interromperia o sistema de mensagens duplex.

Nenhum método adequado para substituir

Você poderá ver esse erro se estiver usando código de blogs ou documentações mais antigas. Verifique se você não está referenciando nomes de métodos que foram alterados ou preteridos (como OnConnectedAsync).

HostContextExtensions.WebSocketServerUrl é nulo

Este comportamento ocorre por design. Esse membro foi preterido e não deve ser usado.

Erro "Uma rota chamada 'signalr.hubs' já está na coleção de rotas"

Esse erro será visto se MapSignalR for chamado duas vezes pelo aplicativo. Alguns aplicativos de exemplo chamam MapSignalR diretamente na classe Startup; outros fazem a chamada em uma classe wrapper. Verifique se o aplicativo não faz as duas coisas.

WebSocket não é usado

Se você verificou que o servidor e os clientes atendem aos requisitos do WebSocket (listado no documento Plataformas Com Suporte ), você precisará habilitar o WebSocket em seu servidor. As instruções para fazer isso podem ser encontradas aqui.

$.connection é indefinido

Esse erro indica que os scripts em uma página não estão sendo carregados corretamente ou que o proxy do hub não está acessível ou está sendo acessado incorretamente. Verifique se as referências de script em sua página correspondem aos scripts carregados em seu projeto e se /signalr/hubs podem ser acessados em um navegador quando o servidor estiver em execução.

Um ou mais tipos necessários para compilar uma expressão dinâmica não podem ser encontrados

Esse erro indica que a Microsoft.CSharp biblioteca está ausente. Adicione-o na guia Assemblies-Framework>.

O estado do chamador não pode ser acessado de Clients.Caller no Visual Basic ou em um hub fortemente tipado; O erro "Conversão do tipo 'Task(Of Object)' para o tipo 'String' não é válida"

Para acessar o estado do chamador no Visual Basic ou em um hub fortemente tipado, use a Clients.CallerState propriedade (introduzida no SignalR 2.1) em vez de Clients.Caller.

Problemas do Visual Studio

Esta seção descreve os problemas encontrados no Visual Studio.

O nó Documentos de Script não aparece no Gerenciador de Soluções

Alguns de nossos tutoriais direcionam você para o nó "Documentos de Script" em Gerenciador de Soluções durante a depuração. Esse nó é produzido pelo depurador JavaScript e só aparecerá durante a depuração de clientes do navegador na Internet Explorer; o nó não será exibido se o Chrome ou o Firefox forem usados. O depurador JavaScript também não será executado se outro depurador de cliente estiver em execução, como o depurador Silverlight.

O SignalR não funciona no Visual Studio 2008 ou anterior

Este comportamento ocorre por design. O SignalR requer .NET Framework 4 ou posterior; isso requer que os aplicativos SignalR sejam desenvolvidos no Visual Studio 2010 ou posterior. O componente de servidor do SignalR requer .NET Framework 4.5.

Problemas do IIS

Esta seção contém problemas com os Serviços de Informações da Internet.

O SignalR funciona no servidor de desenvolvimento do Visual Studio, mas não no IIS

O SignalR tem suporte no IIS 7.0 e 7.5, mas o suporte para URLs sem extensão deve ser adicionado. Para adicionar suporte para URLs sem extensão, consulte https://support.microsoft.com/kb/980368

O SignalR requer que ASP.NET sejam instalados no servidor (ASP.NET não está instalado no IIS por padrão). Para instalar ASP.NET, consulte Downloads de ASP.NET.

Problemas do Microsoft Azure

Esta seção contém problemas com o Microsoft Azure.

FileLoadException ao hospedar o SignalR em uma função de trabalho do Azure

Hospedar o SignalR em uma Função de Trabalho do Azure pode resultar na exceção "Não foi possível carregar o arquivo ou o assembly 'Microsoft.Owin, Version=2.0.0.0". Esse é um problema conhecido com o NuGet; Os redirecionamentos de associação não são adicionados automaticamente em projetos da Função de Trabalho do Azure. Para corrigir isso, você pode adicionar os redirecionamentos de associação manualmente. Adicione as linhas a seguir ao arquivo para seu app.config projeto de Função de Trabalho.

<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>

As mensagens não são recebidas por meio do backplane do Azure após a alteração de nomes de tópicos

Os tópicos usados pelo backplane do Azure são mantidos internamente; eles não se destinam a serem configuráveis pelo usuário.