Tutorial: criar um aplicativo de notificação sem servidor com o Azure Functions e o serviço Azure Web PubSub

O serviço Azure Web PubSub ajuda você a criar aplicativos Web de mensagens em tempo real usando WebSockets. O Azure Functions é uma plataforma sem servidor que permite executar seu código sem gerenciar qualquer infraestrutura. Neste tutorial, você aprenderá a usar o serviço Azure Web PubSub e o Azure Functions para criar um aplicativo sem servidor com mensagens em tempo real em cenários de notificação.

Neste tutorial, você aprenderá como:

  • Criar um aplicativo de notificação sem servidor
  • Trabalhar com associações de entrada e saída de função do Web PubSub
  • Executar as funções de exemplo localmente
  • Implantar a função no aplicativo de funções do Azure

Pré-requisitos

Caso você não tenha uma assinatura do Azure, crie uma conta gratuita do Azure antes de começar.

Entrar no Azure

Entre no portal do Azure em https://portal.azure.com/ com sua conta do Azure.

Criar uma instância do serviço Azure Web PubSub

Seu aplicativo se conectará a uma instância do serviço Web PubSub no Azure.

  1. Selecione no botão Novo localizado no canto superior esquerdo do portal do Azure. Na tela Novo, digite Web PubSub na caixa de pesquisa e pressione ENTER. (Você também pode pesquisar o Azure Web PubSub na categoria Web.)

    Screenshot of searching the Azure Web PubSub in portal.

  2. Selecione Web PubSub nos resultados da pesquisa e escolha Criar.

  3. Insira as configurações a seguir.

    Configuração Valor sugerido Descrição
    Nome do recurso Nome globalmente exclusivo O Nome globalmente exclusivo que identifica a nova instância do serviço Azure Web PubSub. Os caracteres válidos são a-z, A-Z, 0-9 e -.
    Assinatura Sua assinatura A assinatura do Azure na qual essa nova instância do serviço Azure Web PubSub será criada.
    Grupo de Recursos myResourceGroup Nome do novo grupo de recursos no qual a instância do serviço Azure Web PubSub será criada.
    Localidade Oeste dos EUA Selecione uma região perto de você.
    Tipo de preços Grátis Primeiro, você pode experimentar o serviço Azure Web PubSub gratuitamente. Saiba mais detalhes sobre os tipos de preços do serviço Azure Web PubSub
    Contagem de unidades - A contagem de unidades especifica quantas conexões a instância do serviço Azure Web PubSub pode aceitar. Cada unidade dá suporte a, no máximo, 1.000 conexões simultâneas. Só é configurável na camada Standard.

    Screenshot of creating the Azure Web PubSub instance in portal.

  4. Selecione Criar para começar a implantar a instância do serviço Azure Web PubSub.

Criar e executar as funções localmente

  1. Verifique se você tem o Azure Functions Core Tools instalado. Agora, crie um diretório vazio para o projeto. Execute o comando neste diretório de trabalho. Use uma das opções fornecidas abaixo.

    func init --worker-runtime javascript --model V4
    
  2. Siga as etapas para instalar Microsoft.Azure.WebJobs.Extensions.WebPubSubo .

    Confirme ou atualize host.jsono extensionBundle do para a versão 4.* ou posterior para obter suporte ao Web PubSub. Para atualizar o , abra o host.jsonarquivo no editor e substitua a versão existente extensionBundle para a versão 4.* ou posterior.

    {
        "extensionBundle": {
            "id": "Microsoft.Azure.Functions.ExtensionBundle",
            "version": "[4.*, 5.0.0)"
        }
    }
    
  3. Crie uma função index para ler e hospedar uma página da Web estática para clientes.

    func new -n index -t HttpTrigger
    
    • Atualize src/functions/index.js e copie os seguintes códigos.
      const { app } = require('@azure/functions');
      const { readFile } = require('fs/promises');
      
      app.http('index', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          handler: async (context) => {
              const content = await readFile('index.html', 'utf8', (err, data) => {
                  if (err) {
                      context.err(err)
                      return
                  }
              });
      
              return { 
                  status: 200,
                  headers: { 
                      'Content-Type': 'text/html'
                  }, 
                  body: content, 
              };
          }
      });
      
  4. Crie uma função negotiate para ajudar os clientes a obterem a URL de conexão do serviço com o token de acesso.

    func new -n negotiate -t HttpTrigger
    
    • Atualize src/functions/negotiate.js e copie os seguintes códigos.
      const { app, input } = require('@azure/functions');
      
      const connection = input.generic({
          type: 'webPubSubConnection',
          name: 'connection',
          hub: 'notification'
      });
      
      app.http('negotiate', {
          methods: ['GET', 'POST'],
          authLevel: 'anonymous',
          extraInputs: [connection],
          handler: async (request, context) => {
              return { body: JSON.stringify(context.extraInputs.get('connection')) };
          },
      });
      
  5. Crie uma função notification para a qual gerar notificações com TimerTrigger.

    func new -n notification -t TimerTrigger
    
    • Atualize src/functions/notification.js e copie os seguintes códigos.
      const { app, output } = require('@azure/functions');
      
      const wpsAction = output.generic({
          type: 'webPubSub',
          name: 'action',
          hub: 'notification'
      });
      
      app.timer('notification', {
          schedule: "*/10 * * * * *",
          extraOutputs: [wpsAction],
          handler: (myTimer, context) => {
              context.extraOutputs.set(wpsAction, {
                  actionName: 'sendToAll',
                  data: `[DateTime: ${new Date()}] Temperature: ${getValue(22, 1)}\xB0C, Humidity: ${getValue(40, 2)}%`,
                  dataType: 'text',
              });
          },
      });
      
      function getValue(baseNum, floatNum) {
          return (baseNum + 2 * floatNum * (Math.random() - 0.5)).toFixed(3);
      }
      
  6. Adicione a página única do cliente index.html na pasta raiz do projeto e copie o conteúdo.

    <html>
        <body>
        <h1>Azure Web PubSub Notification</h1>
        <div id="messages"></div>
        <script>
            (async function () {
                let messages = document.querySelector('#messages');
                let res = await fetch(`${window.location.origin}/api/negotiate`);
                let url = await res.json();
                let ws = new WebSocket(url.url);
                ws.onopen = () => console.log('connected');
    
                ws.onmessage = event => {
                    let m = document.createElement('p');
                    m.innerText = event.data;
                    messages.appendChild(m);
                };
            })();
        </script>
        </body>
    </html>
    
  7. Configurar e executar o aplicativo do Azure Functions

    • No navegador, abra o portal do Azure e confirme se a instância do serviço Web PubSub implantada anteriormente foi criada com êxito. Navegue até a instância.
    • Selecione Chaves e copie a cadeia de conexão.

    Screenshot of copying the Web PubSub connection string.

    Execute o comando na pasta de funções para definir a cadeia de conexão do serviço. Substitua <connection-string> pelo seu valor, conforme necessário.

    func settings add WebPubSubConnectionString "<connection-string>"
    

    Observação

    O TimerTrigger usado no exemplo tem dependência no Armazenamento do Azure, mas você pode usar um emulador de armazenamento local quando a função estiver sendo executada localmente. Se ocorrer algum erro como There was an error performing a read operation on the Blob Storage Secret Repository. Please ensure the 'AzureWebJobsStorage' connection string is valid., você precisará baixar e habilitar o Emulador de Armazenamento.

    Agora você pode executar a função local com o comando.

    func start --port 7071
    

    E verificando os logs em execução, você pode ir até a página estática do host local acessando: http://localhost:7071/api/index.

    Observação

    Alguns navegadores são redirecionados automaticamente para https, o que leva à URL incorreta. Sugira o uso de Edge e verifique novamente a URL se a renderização não for bem-sucedida.

Implantar o aplicativo de funções no Azure

Antes de poder implantar o código da função no Azure, você precisa criar três recursos:

  • Um grupo de recursos, que é um contêiner lógico para recursos relacionados.
  • Uma conta de armazenamento, que é usada para manter o estado e outras informações sobre suas funções.
  • Um aplicativo de funções, que fornece o ambiente para a execução do código de função. Um aplicativo de funções é mapeado para seu projeto de função local e permite agrupar funções como uma unidade lógica para facilitar o gerenciamento, a implantação e o compartilhamento de recursos.

Use os comandos a seguir para criar esses itens.

  1. Entrar no Azure:

    az login
    
  2. Crie um grupo de recursos ou ignore essa etapa reutilizando o do serviço do Azure Web PubSub:

    az group create -n WebPubSubFunction -l <REGION>
    
  3. Crie uma conta de armazenamento para uso geral no grupo de recursos e na região:

    az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
    
  4. Criar o aplicativo de funções no Azure:

    az functionapp create --resource-group WebPubSubFunction --consumption-plan-location <REGION> --runtime node --runtime-version 18 --functions-version 4 --name <FUNCIONAPP_NAME> --storage-account <STORAGE_NAME>
    

    Observação

    Verifique a documentação das versões de tempo de execução do Azure Functions para definir o parâmetro --runtime-version para o valor com suporte.

  5. Implantar o projeto de funções no Azure:

    Depois de criar seu aplicativo de função no Azure, agora você está pronto para implantar seu projeto de funções locais usando o comando func azure functionapp publishing .

    func azure functionapp publish <FUNCIONAPP_NAME> --publish-local-settings
    

    Observação

    Aqui estamos implantando as configurações locais local.settings.json junto com o parâmetro de comando --publish-local-settings. Se estiver usando Emulador de Armazenamento do Microsoft Azure, você poderá digitar no para ignorar a substituição desse valor no Azure após a mensagem de prompt: App setting AzureWebJobsStorage is different between azure and local.settings.json, Would you like to overwrite value in azure? [yes/no/show]. Além disso, você pode atualizar as configurações do Aplicativo de Funções no Portal do Azure ->Configurações ->Configuração.

  6. Agora você pode verificar o site no Aplicativo de funções do Azure navegando até a URL: https://<FUNCIONAPP_NAME>.azurewebsites.net/api/index.

Limpar recursos

Se você não pretende continuar usando este aplicativo, exclua todos os recursos criados por este documento com as seguintes etapas para não gerar custos:

  1. No portal do Azure, selecione Grupos de recursos na extremidade esquerda, depois selecione o recurso de grupo que você criou. Use a caixa de pesquisa para localizar o grupo de recursos pelo nome.

  2. Na janela que será aberta, selecione o grupo de recursos e escolha Excluir grupo de recursos.

  3. Na nova janela, digite o nome do grupo de recursos a ser excluído e selecione Excluir.

Próximas etapas

Neste início rápido, você aprendeu a executar um aplicativo de chat sem servidor. Agora, você pode começar a criar seu próprio aplicativo.