Partilhar via


Guia de início rápido: criar uma sala de chat usando o Serviço SignalR

O Serviço Azure SignalR é um serviço do Azure que ajuda os programadores a facilmente criar aplicações web com funcionalidades em tempo real.

Este artigo mostra-lhe como começar a utilizar o Azure SignalR Service. Neste início rápido, você criará um aplicativo de bate-papo usando um aplicativo Web ASP.NET Core. Esta aplicação irá fazer uma ligação ao seu recurso do Azure SignalR Service para ativar as atualizações de conteúdos em tempo real. Você hospedará o aplicativo Web localmente e se conectará a vários clientes de navegador. Cada cliente poderá enviar atualizações de conteúdos para todos os outros clientes.

Pode utilizar qualquer editor de código para concluir os passos deste início rápido. Uma opção é o Visual Studio Code, que está disponível nas plataformas Windows, macOS e Linux.

O código deste tutorial está disponível para transferência no repositório do GitHub AzureSignalR-samples. Você pode criar os recursos do Azure usados neste início rápido seguindo o script Criar um Serviço SignalR.

Se não tiver uma subscrição do Azure, crie uma conta gratuita antes de começar.

Pronto para começar?

Pré-requisitos

  • Instale o SDK mais recente do .NET Core.
  • Baixe ou clone o repositório GitHub de exemplo do AzureSignalR.

Tem problemas? Experimente o guia de resolução de problemas ou informe-nos.

Criar um recurso do Azure SignalR

Nesta seção, você cria uma instância básica do Azure SignalR para usar em seu aplicativo. As etapas a seguir usam o portal do Azure para criar uma nova instância, mas você também pode usar a CLI do Azure. Para obter mais informações, consulte o comando az signalr create na Referência da CLI do Serviço Azure SignalR.

  1. Inicie sessão no portal do Azure.
  2. No canto superior esquerdo da página, selecione + Criar um recurso.
  3. Na página Criar um recurso, na caixa de texto Serviços de pesquisa e marketplace, digite signalr e selecione Serviço SignalR na lista.
  4. Na página Serviço SignalR, selecione Criar.
  5. Na guia Noções básicas, você insere as informações essenciais para sua nova instância do Serviço SignalR. Introduza os seguintes valores:
Campo Valor sugerido Description
Subscrição Selecione a sua subscrição Selecione a assinatura que você deseja usar para criar uma nova instância do Serviço SignalR.
Grupo de recursos Criar um grupo de recursos chamado SignalRTestResources Selecione ou crie um grupo de recursos para o seu recurso SignalR. É útil criar um novo grupo de recursos para este tutorial em vez de usar um grupo de recursos existente. Para liberar recursos depois de concluir o tutorial, exclua o grupo de recursos.

A exclusão de um grupo de recursos também exclui todos os recursos que pertencem ao grupo. Esta ação não pode ser anulada. Antes de excluir um grupo de recursos, verifique se ele não contém recursos que você deseja manter.

Para obter mais informações, veja Utilizar grupos de recursos para gerir os recursos do Azure.
Nome do recurso testsignalr Introduza um nome de recurso exclusivo para utilizar no recurso do SignalR. Se o testsignalr já estiver em sua região, adicione um dígito ou caractere até que o nome seja exclusivo.

O nome deve ser uma cadeia de 1 a 63 caracteres e conter apenas números, letras e o caractere hífen (-). O nome não pode começar ou terminar com o caractere de hífen e os caracteres de hífen consecutivos não são válidos.
Região Escolha a sua região Selecione a região apropriada para sua nova instância do Serviço SignalR.

O Serviço Azure SignalR não está atualmente disponível em todas as regiões. Para obter mais informações, consulte Disponibilidade da região do Serviço Azure SignalR
Escalão de preço Selecione Alterar e, em seguida, escolha Gratuito (Somente desenvolvimento/teste). Escolha Selecionar para confirmar sua escolha de nível de preço. O Serviço Azure SignalR tem três níveis de preço: Gratuito, Standard e Premium. Os tutoriais usam o nível Gratuito , salvo indicação em contrário nos pré-requisitos.

Para obter mais informações sobre as diferenças de funcionalidade entre camadas e preços, consulte Preços do Serviço Azure SignalR
Modo de serviço Escolha o modo de serviço apropriado Use Padrão quando hospedar a lógica do hub SignalR em seus aplicativos Web e usar o serviço SignalR como proxy. Use Serverless quando usar tecnologias Serverless , como o Azure Functions, para hospedar a lógica do hub SignalR.

O modo clássico é apenas para compatibilidade com versões anteriores e não é recomendado o uso.

Para obter mais informações, consulte Modo de serviço no Serviço Azure SignalR.

Não é necessário alterar as configurações nas guias Rede e Tags para os tutoriais do SignalR.

  1. Selecione o botão Rever + criar na parte inferior do separador Noções básicas .
  2. No separador Rever + criar, reveja os valores e, em seguida, selecione Criar. Leva alguns momentos para que a implantação seja concluída.
  3. Quando a implantação estiver concluída, selecione o botão Ir para recurso.
  4. Na página de recursos do SignalR, selecione Teclas no menu à esquerda, em Configurações.
  5. Copie a cadeia de conexão para a chave primária. Você precisa dessa cadeia de conexão para configurar seu aplicativo posteriormente neste tutorial.

Criar uma aplicação Web ASP.NET Core

Nesta seção, você usa a interface de linha de comando (CLI) do .NET Core para criar um projeto de aplicativo Web ASP.NET Core MVC. A vantagem de usar a CLI do .NET Core em relação ao Visual Studio é que ela está disponível nas plataformas Windows, macOS e Linux.

  1. Crie uma pasta para o seu projeto. Este guia de início rápido usa a pasta chattest .

  2. Na nova pasta, execute o seguinte comando para criar o projeto:

    dotnet new web
    

Adicionar o Secret Manager ao projeto

Nesta seção, você adicionará a ferramenta Gerenciador Secreto ao seu projeto. A ferramenta Secret Manager armazena dados confidenciais para o trabalho de desenvolvimento fora da árvore do projeto. Essa abordagem ajuda a evitar o compartilhamento acidental de segredos do aplicativo no código-fonte.

  1. Na pasta, inicie UserSecretsId executando o seguinte comando:

    dotnet user-secrets init
    
  2. Adicione um segredo denominado Azure:SignalR:ConnectionString ao Secret Manager.

    Este segredo irá conter a cadeia de ligação para aceder ao seu recurso do SignalR Service. Azure:SignalR:ConnectionString é a chave de configuração padrão que o SignalR procura para estabelecer uma conexão. Substitua o valor no comando a seguir pela cadeia de conexão do recurso do Serviço SignalR.

    Você deve executar esse comando no mesmo diretório que o csproj arquivo.

    dotnet user-secrets set Azure:SignalR:ConnectionString "<Your connection string>"
    

    O Secret Manager será usado apenas para testar o aplicativo Web enquanto ele estiver hospedado localmente. Em um tutorial posterior, você implantará o aplicativo Web de bate-papo no Azure. Depois que o aplicativo Web for implantado no Azure, você usará uma configuração de aplicativo em vez de armazenar a cadeia de conexão com o Gerenciador Secreto.

    Esse segredo é acessado com a API de configuração. Dois pontos (:) funcionam no nome da configuração com a API de configuração em todas as plataformas suportadas. Consulte Configuração por ambiente.

Adicionar o Azure SignalR à aplicação Web

  1. Adicione uma referência ao Microsoft.Azure.SignalR pacote NuGet executando o seguinte comando:

    dotnet add package Microsoft.Azure.SignalR
    
  2. Abra Program.cs e atualize o código para o seguinte, ele chama os métodos e AddAzureSignalR() para usar o AddSignalR() Serviço Azure SignalR:

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddSignalR().AddAzureSignalR();
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseRouting();
    app.UseStaticFiles();
    app.MapHub<ChatSampleHub>("/chat");
    app.Run();
    

    Não passar um parâmetro para significa que ele usa a chave de configuração padrão para AddAzureSignalR() a cadeia de conexão de recurso do Serviço SignalR. A chave de configuração padrão é Azure:SignalR:ConnectionString. Ele também usa ChatSampleHub o que vamos criar na seção abaixo.

Adicionar a classe Hub

No SignalR, um hub é um componente central que expõe um conjunto de métodos que podem ser chamados pelo cliente. Nesta secção, vai definir uma classe hub com dois métodos:

  • BroadcastMessage: este método transmite uma mensagem para todos os clientes.
  • Echo: este método envia uma mensagem novamente para o autor da chamada.

Ambos os métodos usam a Clients interface que o ASP.NET Core SignalR SDK fornece. Esta interface dá-lhe acesso a todos os clientes ligados, para que possa enviar conteúdo para os seus clientes.

  1. No diretório do projeto, adicione uma pasta nova designada Hub. Adicione um novo arquivo de código de hub chamado ChatSampleHub.cs à nova pasta.

  2. Adicione o seguinte código ao ChatSampleHub.cs para definir sua classe de hub e salvar o arquivo.

    using Microsoft.AspNetCore.SignalR;
    
    public class ChatSampleHub : Hub
    {
        public Task BroadcastMessage(string name, string message) =>
            Clients.All.SendAsync("broadcastMessage", name, message);
    
        public Task Echo(string name, string message) =>
            Clients.Client(Context.ConnectionId)
                    .SendAsync("echo", name, $"{message} (echo from server)");
    }
    

Adicionar a interface do cliente para o aplicativo Web

A interface do usuário cliente para este aplicativo de sala de chat consistirá em HTML e JavaScript em um arquivo chamado index.html no diretório wwwroot .

Copie o arquivo css/site.css da pasta wwwroot do repositório de amostras. Substitua o css/site.css do seu projeto pelo que você copiou.

Crie um novo arquivo no diretório wwwroot chamado index.html, copie e cole o seguinte HTML no arquivo recém-criado.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <meta name="viewport" content="width=device-width">
  <meta http-equiv="Pragma" content="no-cache" />
  <meta http-equiv="Expires" content="0" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet" />
  <link href="css/site.css" rel="stylesheet" />
  <title>Azure SignalR Group Chat</title>
</head>
<body>
  <h2 class="text-center" style="margin-top: 0; padding-top: 30px; padding-bottom: 30px;">Azure SignalR Group Chat</h2>
  <div class="container" style="height: calc(100% - 110px);">
    <div id="messages" style="background-color: whitesmoke; "></div>
    <div style="width: 100%; border-left-style: ridge; border-right-style: ridge;">
      <textarea id="message" style="width: 100%; padding: 5px 10px; border-style: hidden;"
        placeholder="Type message and press Enter to send..."></textarea>
    </div>
    <div style="overflow: auto; border-style: ridge; border-top-style: hidden;">
      <button class="btn-warning pull-right" id="echo">Echo</button>
      <button class="btn-success pull-right" id="sendmessage">Send</button>
    </div>
  </div>
  <div class="modal alert alert-danger fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <div>Connection Error...</div>
          <div><strong style="font-size: 1.5em;">Hit Refresh/F5</strong> to rejoin. ;)</div>
        </div>
      </div>
    </div>
  </div>

  <!--Reference the SignalR library. -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>

  <!--Add script to update the page and send messages.-->
  <script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function () {
      function getUserName() {
        function generateRandomName() {
          return Math.random().toString(36).substring(2, 10);
        }

        // Get the user name and store it to prepend to messages.
        var username = generateRandomName();
        var promptMessage = "Enter your name:";
        do {
          username = prompt(promptMessage, username);
          if (!username || username.startsWith("_") || username.indexOf("<") > -1 || username.indexOf(">") > -1) {
            username = "";
            promptMessage = "Invalid input. Enter your name:";
          }
        } while (!username)
        return username;
      }

      username = getUserName();
      // Set initial focus to message input box.
      var messageInput = document.getElementById("message");
      messageInput.focus();

      function createMessageEntry(encodedName, encodedMsg) {
        var entry = document.createElement("div");
        entry.classList.add("message-entry");
        if (encodedName === "_SYSTEM_") {
          entry.innerHTML = encodedMsg;
          entry.classList.add("text-center");
          entry.classList.add("system-message");
        } else if (encodedName === "_BROADCAST_") {
          entry.classList.add("text-center");
          entry.innerHTML = `<div class="text-center broadcast-message">${encodedMsg}</div>`;
        } else if (encodedName === username) {
          entry.innerHTML = `<div class="message-avatar pull-right">${encodedName}</div>` +
            `<div class="message-content pull-right">${encodedMsg}<div>`;
        } else {
          entry.innerHTML = `<div class="message-avatar pull-left">${encodedName}</div>` +
            `<div class="message-content pull-left">${encodedMsg}<div>`;
        }
        return entry;
      }

      function appendMessage(encodedName, encodedMsg) {
        var messageEntry = createMessageEntry(encodedName, encodedMsg);
        var messageBox = document.getElementById("messages");
        messageBox.appendChild(messageEntry);
        messageBox.scrollTop = messageBox.scrollHeight;
      }

      function bindConnectionMessage(connection) {
        var messageCallback = function (name, message) {
          if (!message) return;
          // Html encode display name and message.
          var encodedName = name;
          var encodedMsg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
          appendMessage(encodedName, encodedMsg);
        };
        // Create a function that the hub can call to broadcast messages.
        connection.on("broadcastMessage", messageCallback);
        connection.on("echo", messageCallback);
        connection.onclose(onConnectionError);
      }

      function onConnected(connection) {
        console.log("connection started");
        connection.send("broadcastMessage", "_SYSTEM_", username + " JOINED");
        document.getElementById("sendmessage").addEventListener("click", function (event) {
          // Call the broadcastMessage method on the hub.
          if (messageInput.value) {
            connection.send("broadcastMessage", username, messageInput.value)
              .catch((e) => appendMessage("_BROADCAST_", e.message));
          }

          // Clear text box and reset focus for next comment.
          messageInput.value = "";
          messageInput.focus();
          event.preventDefault();
        });
        document.getElementById("message").addEventListener("keypress", function (event) {
          if (event.keyCode === 13) {
            event.preventDefault();
            document.getElementById("sendmessage").click();
            return false;
          }
        });
        document.getElementById("echo").addEventListener("click", function (event) {
          // Call the echo method on the hub.
          connection.send("echo", username, messageInput.value);

          // Clear text box and reset focus for next comment.
          messageInput.value = "";
          messageInput.focus();
          event.preventDefault();
        });
      }

      function onConnectionError(error) {
        if (error && error.message) {
          console.error(error.message);
        }
        var modal = document.getElementById("myModal");
        modal.classList.add("in");
        modal.style = "display: block;";
      }

      var connection = new signalR.HubConnectionBuilder()
        .withUrl("/chat")
        .build();
      bindConnectionMessage(connection);
      connection.start()
        .then(function () {
          onConnected(connection);
        })
        .catch(function (error) {
          console.error(error.message);
        });
    });
  </script>
</body>
</html>

O código em index.html chama HubConnectionBuilder.build() para fazer uma conexão HTTP com o recurso Azure SignalR.

Se a ligação for bem-sucedida, é transmitida para bindConnectionMessage, que adiciona processadores de eventos para envios de conteúdos de entrada para o cliente.

HubConnection.start() inicia a comunicação com o hub. Em seguida, onConnected() adiciona os manipuladores de eventos button. Estes processadores utilizam a ligação para permitir que este cliente envie atualizações de conteúdos para todos os clientes ligados.

Crie e execute o aplicativo localmente

  1. Execute o seguinte comando para executar o aplicativo Web localmente:

    dotnet run
    

    O aplicativo será hospedado localmente com saída contendo a URL localhost, por exemplo, da seguinte forma:

    Building...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5000
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    
  2. Abra duas janelas do navegador. Em cada navegador, vá para o URL localhost mostrado na janela de saída, por exemplo, http://localhost:5000/ como mostra a janela de saída acima. Ser-lhe-á pedido que introduza o seu nome. Insira um nome de cliente para ambos os clientes e teste o conteúdo da mensagem de envio entre ambos os clientes usando o botão Enviar .

    Example of an Azure SignalR group chat

Clean up resources (Limpar recursos)

Se você continuar para o próximo tutorial, poderá manter os recursos criados neste início rápido e reutilizá-los.

Se você tiver terminado com o aplicativo de exemplo de início rápido, poderá excluir os recursos do Azure criados neste início rápido para evitar cobranças.

Importante

A exclusão de um grupo de recursos é irreversível e inclui todos os recursos desse grupo. Confirme que não elimina acidentalmente o grupo de recursos ou recursos errados. Se você criou os recursos neste exemplo em um grupo de recursos existente que contém recursos que deseja manter, você pode excluir cada recurso individualmente de sua folha em vez de excluir o grupo de recursos.

Inicie sessão no Portal do Azure e selecione Grupos de recursos.

Na caixa de texto Filtrar por nome, digite o nome do grupo de recursos. As instruções neste início rápido utilizaram um grupo de recursos denominado SignalRTestResources. No seu grupo de recursos na lista de resultados, selecione as reticências (...) >Excluir grupo de recursos.

Selections for deleting a resource group

É-lhe pedido que confirme a eliminação do grupo de recursos. Insira o nome do grupo de recursos a ser confirmado e selecione Excluir.

Após alguns instantes, o grupo de recursos e todos os respetivos recursos são eliminados.

Tem problemas? Experimente o guia de resolução de problemas ou informe-nos.

Próximos passos

Neste início rápido, você criou um novo recurso do Serviço Azure SignalR. Em seguida, você o usou com um aplicativo Web ASP.NET Core para enviar atualizações de conteúdo em tempo real para vários clientes conectados. Para saber mais sobre como usar o Serviço SignalR do Azure, continue para o tutorial que demonstra a autenticação.

Azure SignalR Service authentication (Autenticação do Azure SignalR Service)