Introdução ao 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 artigo descreve o que é o SignalR e algumas das soluções que ele foi projetado para criar.
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 perguntas que não estão diretamente relacionadas ao tutorial, poderá postá-las no fórum do ASP.NET SignalR ou StackOverflow.com.
O que é o SignalR?
ASP.NET SignalR é uma biblioteca para desenvolvedores de ASP.NET que simplifica o processo de adição de funcionalidades da Web em tempo real aos aplicativos. A funcionalidade da Web em tempo real é a capacidade de fazer com que o código do servidor envie conteúdo por push para clientes conectados instantaneamente à medida que ele se torna disponível, em vez de fazer com que o servidor aguarde um cliente solicitar novos dados.
O SignalR pode ser usado para adicionar qualquer tipo de funcionalidade da Web "em tempo real" ao aplicativo ASP.NET. Embora o chat seja frequentemente usado como exemplo, você pode fazer muito mais. Sempre que um usuário atualiza uma página da Web para ver novos dados ou a página implementa sondagem longa para recuperar novos dados, ele é um candidato para usar o SignalR. Exemplos incluem painéis e aplicativos de monitoramento, aplicativos colaborativos (como edição simultânea de documentos), atualizações de progresso do trabalho e formulários em tempo real.
O SignalR também permite tipos completamente novos de aplicativos Web que exigem atualizações de alta frequência do servidor, por exemplo, jogos em tempo real.
O SignalR fornece uma API simples para criar RPC (chamadas de procedimento remoto) de servidor para cliente que chamam funções JavaScript em navegadores cliente (e outras plataformas de cliente) do código .NET do lado do servidor. O SignalR também inclui a API para gerenciamento de conexões (por exemplo, eventos de conexão e desconexão) e conexões de agrupamento.
O SignalR lida com o gerenciamento de conexões automaticamente e permite transmitir mensagens a todos os clientes conectados ao mesmo tempo, como uma sala de chat. Você também pode enviar mensagens para clientes específicos. A conexão entre o cliente e o servidor é persistente, diferente de uma conexão HTTP clássica, que é restabelecida para cada comunicação.
O SignalR dá suporte à funcionalidade "push do servidor", na qual o código do servidor pode chamar o código do cliente no navegador usando chamadas de procedimento remoto (RPC), em vez do modelo de solicitação-resposta comum na Web hoje em dia.
Os aplicativos SignalR podem escalar horizontalmente para milhares de clientes usando provedores de expansão internos e de terceiros.
Os provedores internos incluem:
Provedores de terceiros incluem:
O SignalR é de software livre, acessível por meio do GitHub.
SignalR e WebSocket
O SignalR usa o novo transporte WebSocket quando disponível e volta para transportes mais antigos, quando necessário. Embora você certamente possa escrever seu aplicativo usando WebSocket diretamente, usar o SignalR significa que grande parte da funcionalidade extra que você precisaria implementar já está feita para você. Mais importante, isso significa que você pode codificar seu aplicativo para aproveitar o WebSocket sem precisar se preocupar em criar um caminho de código separado para clientes mais antigos. O SignalR também protege você de ter que se preocupar com atualizações para o WebSocket, já que o SignalR é atualizado para dar suporte a alterações no transporte subjacente, fornecendo ao aplicativo uma interface consistente entre versões do WebSocket.
Transportes e fallbacks
O SignalR é uma abstração em alguns dos transportes necessários para fazer trabalho em tempo real entre o cliente e o servidor. O SignalR primeiro tenta estabelecer uma conexão WebSocket, se possível. O WebSocket é o transporte ideal para o SignalR porque ele tem:
- O uso mais eficiente da memória do servidor.
- A menor latência.
- Os recursos mais subjacentes, como comunicação duplex completa entre cliente e servidor.
- Os requisitos mais rigorosos, WebSocket, exigem o servidor:
- Execute no Windows Server 2012 ou no Windows 8.
- .NET Framework 4.5.
Se esses requisitos não forem atendidos, o SignalR tentará usar outros transportes para fazer suas conexões.
Transportes HTML 5
Esses transportes dependem do suporte para HTML 5. Se o navegador cliente não der suporte ao padrão HTML 5, os transportes mais antigos serão usados.
- WebSocket (se o servidor e o navegador indicarem que podem dar suporte ao Websocket). WebSocket é o único transporte que estabelece uma verdadeira conexão bidirecional persistente entre o cliente e o servidor. No entanto, o WebSocket também tem os requisitos mais rigorosos; ele tem suporte total apenas nas versões mais recentes do Microsoft Internet Explorer, Google Chrome e Mozilla Firefox, e tem apenas uma implementação parcial em outros navegadores, como Opera e Safari.
- Eventos enviados pelo servidor, também conhecidos como EventSource (se o navegador der suporte a Eventos Enviados pelo Servidor, que é basicamente todos os navegadores, exceto Internet Explorer.)
Transportes de cometas
Os transportes a seguir são baseados no modelo de aplicativo Web Comet , no qual um navegador ou outro cliente mantém uma solicitação HTTP de longa duração, que o servidor pode usar para enviar dados por push ao cliente sem que o cliente solicite especificamente.
- Quadro Para Sempre (somente para Internet Explorer). O Forever Frame cria um IFrame oculto que faz uma solicitação para um ponto de extremidade no servidor que não é concluído. Em seguida, o servidor envia continuamente o script para o cliente que é executado imediatamente, fornecendo uma conexão unidirecional em tempo real do servidor para o cliente. A conexão do cliente com o servidor usa uma conexão separada do servidor com a conexão do cliente e, como uma solicitação HTTP padrão, uma nova conexão é criada para cada parte dos dados que precisam ser enviados.
- Sondagem longa do Ajax. A sondagem longa não cria uma conexão persistente, mas sonda o servidor com uma solicitação que permanece aberta até que o servidor responda, momento em que a conexão é fechada e uma nova conexão é solicitada imediatamente. Isso pode introduzir alguma latência enquanto a conexão é redefinida.
Para obter mais informações sobre quais transportes têm suporte em quais configurações, consulte Plataformas com suporte.
Processo de seleção de transporte
A lista a seguir mostra as etapas que o SignalR usa para decidir qual transporte usar.
Se o navegador for Internet Explorer 8 ou anterior, a Sondagem Longa será usada.
Se JSONP estiver configurado (ou seja, o
jsonp
parâmetro será definido comotrue
quando a conexão for iniciada), a Sondagem Longa será usada.Se uma conexão entre domínios estiver sendo feita (ou seja, se o ponto de extremidade do SignalR não estiver no mesmo domínio que a página de hospedagem), o WebSocket será usado se os seguintes critérios forem atendidos:
O cliente dá suporte ao CORS (Compartilhamento de Recursos entre Origens). Para obter detalhes sobre quais clientes dão suporte ao CORS, consulte CORS em caniuse.com.
O cliente dá suporte ao WebSocket
O servidor dá suporte a WebSocket
Se qualquer um desses critérios não for atendido, a Sondagem Longa será usada. Para obter mais informações sobre conexões entre domínios, consulte Como estabelecer uma conexão entre domínios.
Se o JSONP não estiver configurado e a conexão não for entre domínios, o WebSocket será usado se o cliente e o servidor derem suporte a ele.
Se o cliente ou o servidor não der suporte ao WebSocket, os Eventos Enviados ao Servidor serão usados se estiverem disponíveis.
Se eventos enviados pelo servidor não estiverem disponíveis, o Quadro Para Sempre será tentado.
Se Forever Frame falhar, a Sondagem Longa será usada.
Monitoramento de transportes
Você pode determinar qual transporte seu aplicativo está usando habilitando o registro em log no hub e abrindo a janela do console no navegador.
Para habilitar o registro em log dos eventos do hub em um navegador, adicione o seguinte comando ao aplicativo cliente:
$.connection.hub.logging = true;
Na Internet Explorer, abra as ferramentas de desenvolvedor pressionando F12 e clique na guia Console.
No Chrome, abra o console pressionando Ctrl+Shift+J.
Com o console aberto e o registro em log habilitado, você poderá ver qual transporte está sendo usado pelo SignalR.
Especificando um transporte
Negociar um transporte leva um determinado tempo e recursos de cliente/servidor. Se os recursos do cliente forem conhecidos, um transporte poderá ser especificado quando a conexão do cliente for iniciada. O snippet de código a seguir demonstra como iniciar uma conexão usando o transporte de Sondagem Longa do Ajax, como seria usado se soubesse que o cliente não dá suporte a nenhum outro protocolo:
connection.start({ transport: 'longPolling' });
Você pode especificar uma ordem de fallback se quiser que um cliente experimente transportes específicos na ordem. O snippet de código a seguir demonstra a tentativa de WebSocket e a falha, indo diretamente para Sondagem Longa.
connection.start({ transport: ['webSockets','longPolling'] });
As constantes de cadeia de caracteres para especificar transportes são definidas da seguinte maneira:
webSockets
foreverFrame
serverSentEvents
longPolling
Conexões e Hubs
A API do SignalR contém dois modelos para comunicação entre clientes e servidores: Conexões Persistentes e Hubs.
Uma Conexão representa um ponto de extremidade simples para enviar mensagens de destinatário único, agrupadas ou transmitidas. A API de Conexão Persistente (representada no código .NET pela classe PersistentConnection) fornece ao desenvolvedor acesso direto ao protocolo de comunicação de baixo nível que o SignalR expõe. O uso do modelo de comunicação Conexões será familiar para desenvolvedores que usaram APIs baseadas em conexão, como o Windows Communication Foundation.
Um Hub é um pipeline de nível mais alto criado com base na API de Conexão que permite que o cliente e o servidor chamem métodos uns nos outros diretamente. O SignalR lida com a expedição entre limites do computador como se fosse magic, permitindo que os clientes chamem métodos no servidor tão facilmente quanto métodos locais e vice-versa. O uso do modelo de comunicação de Hubs será familiar para desenvolvedores que usaram APIs de invocação remota, como comunicação remota do .NET. O uso de um Hub também permite que você passe parâmetros fortemente tipados para métodos, habilitando a associação de modelo.
Diagrama de arquitetura
O diagrama a seguir mostra a relação entre Hubs, Conexões Persistentes e as tecnologias subjacentes usadas para transportes.
Como os Hubs funcionam
Quando o código do lado do servidor chama um método no cliente, um pacote é enviado pelo transporte ativo que contém o nome e os parâmetros do método a ser chamado (quando um objeto é enviado como um parâmetro de método, ele é serializado usando JSON). Em seguida, o cliente corresponde o nome do método aos métodos definidos no código do lado do cliente. Se houver uma correspondência, o método do cliente será executado usando os dados de parâmetro desserializados.
A chamada de método pode ser monitorada usando ferramentas como o Fiddler. A imagem a seguir mostra uma chamada de método enviada de um servidor SignalR para um cliente de navegador da Web no painel Logs do Fiddler. A chamada de método está sendo enviada de um hub chamado MoveShapeHub
e o método que está sendo invocado é chamado updateShape
.
Neste exemplo, o nome do hub é identificado com o H
parâmetro ; o nome do método é identificado com o M
parâmetro e os dados que estão sendo enviados para o método são identificados com o A
parâmetro . O aplicativo que gerou essa mensagem é criado no tutorial Em tempo real de alta frequência .
Escolhendo um modelo de comunicação
A maioria dos aplicativos deve usar a API de Hubs. A API de Conexões pode ser usada nas seguintes circunstâncias:
- O formato da mensagem real enviada precisa ser especificado.
- O desenvolvedor prefere trabalhar com um modelo de mensagens e expedição em vez de um modelo de invocação remota.
- Um aplicativo existente que usa um modelo de mensagens está sendo portado para usar o SignalR.