Laboratório prático: Aplicativos Web em tempo real com SignalR
Aviso
Esta documentação não é para a versão mais recente do SignalR. Dê uma olhada em ASP.NET Core SignalR.
Baixar o Kit de Treinamento do Web Camps, versão de outubro de 2015
Os aplicativos Web em tempo real apresentam a capacidade de enviar por push o conteúdo do lado do servidor para os clientes conectados conforme isso acontece, em tempo real. Para desenvolvedores ASP.NET, ASP.NET SignalR é uma biblioteca para adicionar funcionalidade da Web em tempo real aos aplicativos. Ele aproveita vários transportes, selecionando automaticamente o melhor transporte disponível, considerando o melhor transporte disponível do cliente e do servidor. Ele aproveita o WebSocket, uma API HTML5 que permite a comunicação bidirecional entre o navegador e o servidor.
O SignalR também fornece uma API simples e de alto nível para fazer RPC de servidor para cliente (chamar funções JavaScript nos navegadores dos clientes do código .NET do lado do servidor) em seu aplicativo ASP.NET, bem como adicionar ganchos úteis para gerenciamento de conexões, como eventos de conexão/desconexão, conexões de agrupamento e autorização.
O SignalR é uma abstração em alguns dos transportes necessários para fazer trabalho em tempo real entre o cliente e o servidor. Uma conexão do SignalR começa como HTTP e, em seguida, é promovida para uma conexão WebSocket , se disponível. O WebSocket é o transporte ideal para o SignalR, pois faz o uso mais eficiente da memória do servidor, tem a menor latência e tem os recursos mais subjacentes (como comunicação duplex completa entre cliente e servidor), mas também tem os requisitos mais rigorosos: o WebSocket exige que o servidor esteja usando o Windows Server 2012 ou o Windows 8, junto com .NET Framework 4.5. Se esses requisitos não forem atendidos, o SignalR tentará usar outros transportes para fazer suas conexões (como sondagem longa do Ajax).
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. 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.
Todos os snippets e código de exemplo estão incluídos no Kit de Treinamento de Campos da Web, versão de outubro de 2015, disponível em https://github.com/Microsoft-Web/WebCampTrainingKit/releases/tag/v2015.10.13b. Observe que o link do Instalador nessa página não funciona mais; em vez disso, use um dos links na seção Ativos.
Visão geral
Objetivos
Neste laboratório prático, você aprenderá a:
- Enviar notificações do servidor para o cliente usando o SignalR.
- Scale Out seu aplicativo SignalR usando SQL Server.
Pré-requisitos
O seguinte é necessário para concluir este laboratório prático:
- Visual Studio Express 2013 para Web ou superior
Instalação
Para executar os exercícios neste laboratório prático, você precisará configurar seu ambiente primeiro.
- Abra uma janela do Windows Explorer e navegue até a pasta Origem do laboratório.
- Clique com o botão direito do mouse em Setup.cmd e selecione Executar como administrador para iniciar o processo de instalação que configurará seu ambiente e instalará os snippets de código do Visual Studio para este laboratório.
- Se a caixa de diálogo Controle de Conta de Usuário for mostrada, confirme a ação para continuar.
Observação
Verifique se você verificou todas as dependências deste laboratório antes de executar a instalação.
Usando os snippets de código
Em todo o documento de laboratório, você será instruído a inserir blocos de código. Para sua conveniência, a maior parte desse código é fornecida como snippets de Visual Studio Code, que você pode acessar de dentro de Visual Studio 2013 para evitar a necessidade de adicioná-lo manualmente.
Observação
Cada exercício é acompanhado por uma solução inicial localizada na pasta Begin do exercício que permite que você siga cada exercício independentemente dos outros. Lembre-se de que os snippets de código adicionados durante um exercício estão ausentes dessas soluções iniciais e podem não funcionar até que você tenha concluído o exercício. Dentro do código-fonte de um exercício, você também encontrará uma pasta End contendo uma solução do Visual Studio com o código que resulta da conclusão das etapas no exercício correspondente. Você pode usar essas soluções como diretrizes se precisar de ajuda adicional enquanto trabalha neste laboratório prático.
Exercícios
Este laboratório prático inclui os seguintes exercícios:
Tempo estimado para concluir este laboratório: 60 minutos
Observação
Ao iniciar o Visual Studio pela primeira vez, você deve selecionar uma das coleções de configurações predefinidas. Cada coleção predefinida foi projetada para corresponder a um estilo de desenvolvimento específico e determina layouts de janela, comportamento do editor, snippets de código do IntelliSense e opções de caixa de diálogo. Os procedimentos neste laboratório descrevem as ações necessárias para realizar uma determinada tarefa no Visual Studio ao usar a coleção Configurações gerais de desenvolvimento . Se você escolher uma coleção de configurações diferente para seu ambiente de desenvolvimento, poderá haver diferenças nas etapas que você deve levar em conta.
Exercício 1: Trabalhando com Real-Time dados usando o SignalR
Embora o chat seja frequentemente usado como exemplo, você pode fazer muito mais com a funcionalidade da Web em tempo real. Sempre que um usuário atualiza uma página da Web para ver novos dados ou a página implementa a sondagem longa do Ajax para recuperar novos dados, você pode usar o SignalR.
O SignalR dá suporte à funcionalidade de transmissão ou push do servidor; ele lida com o gerenciamento de conexões automaticamente. Em conexões HTTP clássicas para comunicação cliente-servidor, a conexão é restabelecida para cada solicitação, mas o SignalR fornece conexão persistente entre o cliente e o servidor. No SignalR, o código do servidor chama um código de cliente no navegador usando RPC (Chamadas de Procedimento Remoto), em vez do modelo de solicitação-resposta que conhecemos hoje.
Neste exercício, você configurará o aplicativo Geek Quiz para usar o SignalR para exibir as estatísticas dashboard com as métricas atualizadas sem a necessidade de atualizar a página inteira.
Tarefa 1 – Explorando a página Estatísticas do Quiz Geek
Nesta tarefa, você percorrerá o aplicativo e verificará como a página de estatísticas é mostrada e como você pode melhorar a maneira como as informações são atualizadas.
Abra Visual Studio Express 2013 para Web e abra a solução GeekQuiz.sln localizada na pasta Source\Ex1-WorkingWithRealTimeData\Begin.
Pressione F5 para executar a solução. A página Fazer logon deve aparecer no navegador.
Executar a solução
Clique em Registrar no canto superior direito da página para criar um novo usuário no aplicativo.
Registrar link
Na página Registrar , insira um Nome de usuário e Senha e clique em Registrar.
Registrando um usuário
O aplicativo registra a nova conta e o usuário é autenticado e redirecionado de volta para a home page mostrando a primeira pergunta do teste.
Abra a página Estatísticas em uma nova janela e coloque a página Página Inicial e Estatísticas lado a lado.
Janelas lado a lado
Na Página Inicial , responda à pergunta clicando em uma das opções.
Respondendo a uma pergunta
Depois de clicar em um dos botões, a resposta deve aparecer.
Pergunta respondida corretamente
Observe que as informações fornecidas na página Estatísticas estão desatualizadas. Atualize a página para ver os resultados atualizados.
Página Estatísticas
Voltar ao Visual Studio e interrompa a depuração.
Tarefa 2 – Adicionar o SignalR ao Geek Quiz para mostrar gráficos online
Nesta tarefa, você adicionará o SignalR à solução e enviará atualizações aos clientes automaticamente quando uma nova resposta for enviada ao servidor.
No menu Ferramentas no Visual Studio, selecione Gerenciador de Pacotes NuGet e clique em Console do Gerenciador de Pacotes.
Na janela Console do Gerenciador de Pacotes , execute o seguinte comando:
Install-Package Microsoft.AspNet.SignalR
Instalação do pacote do SignalR
Observação
Ao instalar pacotes NuGet do SignalR versão 2.0.2 de um novo aplicativo MVC 5, você precisará atualizar manualmente os pacotes OWIN para a versão 2.0.1 (ou superior) antes de instalar o SignalR. Para fazer isso, você pode executar o seguinte script no Console do Gerenciador de Pacotes:
get-package | where-object { $_.Id -like "Microsoft.Owin*"} | Update-Package
Em uma versão futura do SignalR, as dependências OWIN serão atualizadas automaticamente.
Em Gerenciador de Soluções, expanda a pasta Scripts e observe que os arquivos JS do SignalR foram adicionados à solução.
Referências de JavaScript do SignalR
Em Gerenciador de Soluções, clique com o botão direito do mouse no projeto GeekQuiz, selecione Adicionar | Nova Pasta e nomeie-a hubs.
Clique com o botão direito do mouse na pasta Hubs e selecione Adicionar | Novo Item.
Adicionar novo item
Na caixa de diálogo Adicionar Novo Item , selecione o Visual C# | Web | No nó do SignalR no painel esquerdo, selecione Classe do Hub do SignalR (v2) no painel central, nomeie o arquivo StatisticsHub.cs e clique em Adicionar.
Caixa de diálogo Adicionar novo item
Substitua o código na classe StatisticsHub pelo código a seguir.
(Snippet de código – RealTimeSignalr – Ex1 – StatisticsHubClass)
namespace GeekQuiz.Hubs { using Microsoft.AspNet.SignalR; public class StatisticsHub : Hub { } }
Abra Startup.cs e adicione a linha a seguir no final do método Configuration .
(Snippet de código – RealTimeSignalr – Ex1 – MapSignalr)
public void Configuration(IAppBuilder app) { this.ConfigureAuth(app); app.MapSignalR(); }
Abra a página StatisticsService.cs dentro da pasta Serviços e adicione as diretivas using a seguir.
(Snippet de código – RealTimeSignalR – Ex1 – UsingDirectives)
using Microsoft.AspNet.SignalR; using GeekQuiz.Hubs;
Para notificar os clientes conectados sobre atualizações, primeiro recupere um objeto Context para a conexão atual. O objeto Hub contém métodos para enviar mensagens para um único cliente ou difundir para todos os clientes conectados. Adicione o método a seguir à classe StatisticsService para transmitir os dados de estatísticas.
(Snippet de código – RealTimeSignalR – Ex1 – NotifyUpdatesMethod)
public async Task NotifyUpdates() { var hubContext = GlobalHost.ConnectionManager.GetHubContext<StatisticsHub>(); if (hubContext != null) { var stats = await this.GenerateStatistics(); hubContext.Clients.All.updateStatistics(stats); } }
Observação
No código acima, você está usando um nome de método arbitrário para chamar uma função no cliente (ou seja: updateStatistics). O nome do método especificado é interpretado como um objeto dinâmico, o que significa que não há nenhum IntelliSense ou validação em tempo de compilação para ele. A expressão é avaliada em tempo de execução. Quando a chamada de método é executada, o SignalR envia o nome do método e os valores de parâmetro para o cliente. Se o cliente tiver um método que corresponda ao nome, esse método será chamado e os valores de parâmetro serão passados para ele. Se nenhum método correspondente for encontrado no cliente, nenhum erro será gerado. Para obter mais informações, consulte ASP.NET Guia de API dos Hubs do SignalR.
Abra a página TriviaController.cs dentro da pasta Controladores e adicione as diretivas using a seguir.
using GeekQuiz.Services;
Adicione o código realçado a seguir ao método de ação Post .
(Snippet de código – RealTimeSignalR – Ex1 – NotifyUpdatesCall)
public async Task<IHttpActionResult> Post(TriviaAnswer answer) { if (!ModelState.IsValid) { return this.BadRequest(this.ModelState); } answer.UserId = User.Identity.Name; var isCorrect = await this.StoreAsync(answer); var statisticsService = new StatisticsService(this.db); await statisticsService.NotifyUpdates(); return this.Ok<bool>(isCorrect); }
Abra a página Statistics.cshtml dentro dos Modos de Exibição | Pasta Inicial . Localize a seção Scripts e adicione as referências de script a seguir no início da seção.
(Snippet de código – RealTimeSignalR – Ex1 – SignalRScriptReferences)
@section Scripts { @Scripts.Render("~/Scripts/jquery.signalR-2.0.2.min.js"); @Scripts.Render("~/signalr/hubs"); ... }
Observação
Quando você adiciona o SignalR e outras bibliotecas de script ao projeto do Visual Studio, o Gerenciador de Pacotes pode instalar uma versão do arquivo de script do SignalR mais recente do que a versão mostrada neste tópico. Verifique se a referência de script em seu código corresponde à versão da biblioteca de scripts instalada em seu projeto.
Adicione o código realçado a seguir para conectar o cliente ao hub do SignalR e atualizar os dados de estatísticas quando uma nova mensagem for recebida do hub.
(Snippet de código – RealTimeSignalr – Ex1 – SignalRClientCode)
@section Scripts { ... <script> ... var connection = $.hubConnection(); var hub = connection.createHubProxy("StatisticsHub"); hub.on("updateStatistics", function (statistics) { statisticsData = statistics; $("#correctAnswersCounter").text(statistics.CorrectAnswers); $("#incorrectAnswersCounter").text(statistics.IncorrectAnswers); showCharts(statisticsData); }); connection.start(); </script> }
Nesse código, você está criando um Proxy de Hub e registrando um manipulador de eventos para escutar mensagens enviadas pelo servidor. Nesse caso, você escuta mensagens enviadas por meio do método updateStatistics .
Tarefa 3 – Executando a solução
Nesta tarefa, você executará a solução para verificar se a exibição de estatísticas é atualizada automaticamente usando o SignalR depois de responder a uma nova pergunta.
Pressione F5 para executar a solução.
Observação
Se ainda não tiver feito logon no aplicativo, faça logon com o usuário que você criou na Tarefa 1.
Abra a página Estatísticas em uma nova janela e coloque a página Página Inicial e Estatísticas lado a lado como você fez na Tarefa 1.
Na Página Inicial , responda à pergunta clicando em uma das opções.
Respondendo a outra pergunta
Depois de clicar em um dos botões, a resposta deve aparecer. Observe que as informações de Estatísticas na página são atualizadas automaticamente depois de responder à pergunta com as informações atualizadas sem a necessidade de atualizar a página inteira.
Página de estatísticas atualizada após a resposta
Exercício 2: Escalar horizontalmente usando SQL Server
Ao dimensionar um aplicativo Web, você geralmente pode escolher entre escalar verticalmente e escalar horizontalmente as opções. Escalar verticalmente significa usar um servidor maior, com mais recursos (CPU, RAM etc.), enquanto escalar horizontalmente significa adicionar mais servidores para lidar com a carga. O problema com o último é que os clientes podem ser roteado para servidores diferentes. Um cliente conectado a um servidor não receberá mensagens enviadas de outro servidor.
Você pode resolver esses problemas usando um componente chamado backplane para encaminhar mensagens entre servidores. Com um backplane habilitado, cada instância do aplicativo envia mensagens para o backplane e o backplane as encaminha para as outras instâncias do aplicativo.
Atualmente, há três tipos de backplanes para o SignalR:
- Windows Barramento de Serviço do Azure. O Barramento de Serviço é uma infraestrutura de mensagens que permite que os componentes enviem mensagens fracamente acopladas.
- SQL Server. O backplane SQL Server grava mensagens em tabelas SQL. O backplane usa o Service Broker para mensagens eficientes. No entanto, ele também funcionará se o Service Broker não estiver habilitado.
- Redis. O Redis é um repositório chave-valor na memória. O Redis dá suporte a um padrão de publicação/assinatura ("pub/sub") para enviar mensagens.
Cada mensagem é enviada por meio de um barramento de mensagens. Um barramento de mensagens implementa a interface IMessageBus , que fornece uma abstração de publicação/assinatura. Os backplanes funcionam substituindo o IMessageBus padrão por um barramento projetado para esse backplane.
Cada instância de servidor se conecta ao backplane por meio do barramento. Quando uma mensagem é enviada, ela vai para o backplane e o backplane a envia para todos os servidores. Quando um servidor recebe uma mensagem do backplane, ele armazena a mensagem em seu cache local. Em seguida, o servidor entrega mensagens aos clientes de seu cache local.
Para obter mais informações sobre como funciona o backplane do SignalR, leia este artigo.
Observação
Há alguns cenários em que um backplane pode se tornar um gargalo. Aqui estão alguns cenários típicos do SignalR:
- Transmissão de servidor (por exemplo, ticker de ações): os planos de fundo funcionam bem para esse cenário, pois o servidor controla a taxa na qual as mensagens são enviadas.
- Cliente para cliente (por exemplo, chat): nesse cenário, o backplane poderá ser um gargalo se o número de mensagens for dimensionado com o número de clientes; ou seja, se a taxa de mensagens aumentar proporcionalmente à medida que mais clientes ingressarem.
- Tempo real de alta frequência (por exemplo, jogos em tempo real): um backplane não é recomendado para esse cenário.
Neste exercício, você usará SQL Server para distribuir mensagens pelo aplicativo Geek Quiz. Você executará essas tarefas em um único computador de teste para saber como configurar a configuração, mas, para obter o efeito completo, será necessário implantar o aplicativo SignalR em dois ou mais servidores. Você também deve instalar SQL Server em um dos servidores ou em um servidor dedicado separado.
Tarefa 1 – Noções básicas sobre o cenário
Nesta tarefa, você executará duas instâncias do Geek Quiz simulando várias instâncias do IIS em seu computador local. Nesse cenário, ao responder perguntas triviais em um aplicativo, a atualização não será notificada na página de estatísticas da segunda instância. Essa simulação é semelhante a um ambiente em que seu aplicativo é implantado em várias instâncias e usa um balanceador de carga para se comunicar com elas.
Abra a solução Begin.sln localizada na pasta Source/Ex2-ScalingOutWithSQLServer/Begin . Depois de carregada, você observará no servidor Explorer que a solução tem dois projetos com estruturas idênticas, mas nomes diferentes. Isso simulará a execução de duas instâncias do mesmo aplicativo em seu computador local.
Iniciar solução simulando 2 instâncias do Geek Quiz
Abra a página de propriedades da solução clicando com o botão direito do mouse no nó da solução e selecionando Propriedades. Em Projeto de Inicialização, selecione Vários projetos de inicialização e altere o valor Ação para ambos os projetos para Iniciar.
Iniciando vários projetos
Pressione F5 para executar a solução. O aplicativo iniciará duas instâncias do Geek Quiz em portas diferentes, simulando várias instâncias do mesmo aplicativo. Fixe um dos navegadores à esquerda e o outro à direita da tela. Faça logon com suas credenciais ou registre um novo usuário. Depois de conectado, mantenha a página Trivia à esquerda e vá para a página Estatísticas no navegador à direita.
Quiz Geek lado a lado
Quiz geek em portas diferentes
Comece a responder perguntas no navegador esquerdo e você observará que a página Estatísticas no navegador direito não está sendo atualizada. Isso ocorre porque o SignalR usa um cache local para distribuir mensagens entre seus clientes e esse cenário está simulando várias instâncias, portanto, o cache não é compartilhado entre elas. Você pode verificar se o SignalR está funcionando testando as mesmas etapas, mas usando um único aplicativo. Nas tarefas a seguir, você configurará um backplane para replicar as mensagens entre instâncias.
Voltar ao Visual Studio e interrompa a depuração.
Tarefa 2 – Criando o backplane do SQL Server
Nesta tarefa, você criará um banco de dados que servirá como um backplane para o aplicativo Geek Quiz . Você usará SQL Server Pesquisador de Objetos para procurar o servidor e inicializar o banco de dados. Além disso, você habilitará o Service Broker.
No Visual Studio, abra o menu Exibir e selecione SQL Server Pesquisador de Objetos.
Conecte-se à instância do LocalDB clicando com o botão direito do mouse no nó SQL Server e selecionando Adicionar SQL Server... opção.
Adicionando uma instância de SQL Server a SQL Server Pesquisador de Objetos
Defina o nome do servidor como (localdb)\v11.0 e deixe a Autenticação do Windows como seu modo de autenticação. Clique em Conectar para continuar.
Conectando-se ao LocalDB
Agora que você está conectado à instância do LocalDB, será necessário criar um banco de dados que representará o backplane SQL Server para o SignalR. Para fazer isso, clique com o botão direito do mouse no nó Bancos de Dados e selecione Adicionar Novo Banco de Dados.
Adicionando um novo banco de dados
Defina o nome do banco de dados como SignalR e clique em OK para criá-lo.
Criando o banco de dados do SignalR
Observação
Você pode escolher qualquer nome para o banco de dados.
Para receber atualizações com mais eficiência do backplane, é recomendável habilitar o Service Broker para o banco de dados. O Service Broker fornece suporte nativo para mensagens e enfileiramento em SQL Server. O backplane também funciona sem o Service Broker. Abra uma nova consulta clicando com o botão direito do mouse no banco de dados e selecione Nova Consulta.
Abrindo uma nova consulta
Para marcar se o Service Broker está habilitado, consulte a coluna is_broker_enabled na exibição do catálogo sys.databases. Execute o script a seguir na janela de consulta aberta recentemente.
SELECT [name], [service_broker_guid], [is_broker_enabled] FROM [master].[sys].[databases]
Consultando o status do Service Broker
Se o valor da coluna is_broker_enabled no banco de dados for "0", use o comando a seguir para habilitá-lo. Substitua <YOUR-DATABASE> pelo nome definido ao criar o banco de dados (por exemplo: SignalR).
ALTER DATABASE <YOUR-DATABASE> SET ENABLE_BROKER
Habilitando o Service Broker
Observação
Se essa consulta aparecer como deadlock, verifique se não há aplicativos conectados ao BD.
Tarefa 3 – Configurando o aplicativo SignalR
Nesta tarefa, você configurará o Geek Quiz para se conectar ao backplane SQL Server. Primeiro, você adicionará o pacote NuGet SignalR.SqlServer e definirá a cadeia de conexão para o banco de dados de backplane.
Abra o Console do Gerenciador de Pacotes em FerramentasGerenciador de Pacotes> NuGet. Verifique se o projeto GeekQuiz está selecionado na lista suspensa Projeto padrão . Digite o comando a seguir para instalar o pacote NuGet Microsoft.AspNet.SignalR.SqlServer .
Install-Package Microsoft.AspNet.SignalR.SqlServer
Repita a etapa anterior, mas desta vez para o projeto GeekQuiz2.
Para configurar o backplane SQL Server, abra o arquivo Startup.cs do projeto GeekQuiz e adicione o código a seguir ao método Configure. Substitua <YOUR-DATABASE> pelo nome do banco de dados que você usou ao criar o backplane SQL Server. Repita esta etapa para o projeto GeekQuiz2 .
(Snippet de código – RealTimeSignalR – Ex2 – StartupConfiguration)
public class Startup { public void Configuration(IAppBuilder app) { var sqlConnectionString = @"Server=(localdb)\v11.0;Database=<YOUR-DATABASE>;Integrated Security=True;"; GlobalHost.DependencyResolver.UseSqlServer(sqlConnectionString); this.ConfigureAuth(app); app.MapSignalR(); } }
Agora que ambos os projetos estão configurados para usar o backplane SQL Server, pressione F5 para executá-los simultaneamente.
Novamente, o Visual Studio iniciará duas instâncias do Geek Quiz em portas diferentes. Fixe um dos navegadores à esquerda e o outro à direita da tela e faça logon com suas credenciais. Mantenha a página Trivia à esquerda e vá para a página Estatísticas no navegador direito.
Comece a responder perguntas no navegador esquerdo. Desta vez, a página Estatísticas é atualizada graças ao backplane. Alterne entre aplicativos (as estatísticas agora estão à esquerda e o Trivia está à direita) e repita o teste para validar se ele está funcionando para ambas as instâncias. O backplane serve como um cache compartilhado de mensagens para cada servidor conectado, e cada servidor armazenará as mensagens em seu próprio cache local para distribuir aos clientes conectados.
Voltar ao Visual Studio e interrompa a depuração.
O componente de backplane SQL Server gera automaticamente as tabelas necessárias no banco de dados especificado. No painel SQL Server Pesquisador de Objetos, abra o banco de dados que você criou para o backplane (por exemplo: SignalR) e expanda suas tabelas. Você deverá ver as seguintes tabelas:
Tabelas geradas de backplane
Clique com o botão direito do mouse na tabela SignalR.Messages_0 e selecione Exibir Dados.
Exibir tabela de mensagens de backplane do SignalR
Você pode ver as diferentes mensagens enviadas para o Hub ao responder às perguntas triviais. O backplane distribui essas mensagens para qualquer instância conectada.
Tabela de mensagens de backplane
Resumo
Neste laboratório prático, você aprendeu a adicionar o SignalR ao seu aplicativo e enviar notificações do servidor para seus clientes conectados usando Hubs. Além disso, você aprendeu a escalar horizontalmente seu aplicativo usando um componente de backplane quando seu aplicativo é implantado em várias instâncias do IIS.