Tutorial: Creación de una aplicación de notificación sin servidor con Azure Functions y el servicio Azure Web PubSub

El servicio Azure Web PubSub le ayuda a crear aplicaciones web de mensajería en tiempo real mediante WebSockets. Azure Functions es una plataforma sin servidor que le permite ejecutar el código sin tener que administrar ninguna infraestructura. En este tutorial, aprenderá a usar el servicio Azure Web PubSub y Azure Functions para compilar una aplicación sin servidor con mensajería en tiempo real en escenarios de notificación.

En este tutorial, aprenderá a:

  • Compilar una aplicación de notificación sin servidor.
  • Utilizar los enlaces de entrada y salida de funciones de Web PubSub.
  • Ejecutar localmente funciones de ejemplo.
  • Implementar la función en Azure Function App

Requisitos previos

Si no tiene una suscripción a Azure, cree una cuenta gratuita de Azure antes de empezar.

Inicio de sesión en Azure

Inicie sesión en Azure Portal en https://portal.azure.com/ con su cuenta de Azure.

Creación de una instancia de servicio de Azure Web PubSub

La aplicación se conectará a una instancia de servicio de Web PubSub en Azure.

  1. Seleccione el botón Nuevo de la esquina superior izquierda en Azure Portal. En la pantalla "Nuevo", escriba Web PubSub en el cuadro de búsqueda y presione Entrar. (También puede buscar Azure Web PubSub en la categoría Web).

    Screenshot of searching the Azure Web PubSub in portal.

  2. Seleccione Web PubSub en los resultados de la búsqueda y, después, haga clic en Crear.

  3. Escriba la siguiente configuración.

    Configuración Valor sugerido Descripción
    Nombre del recurso Nombre único globalmente Nombre único global que identifica la nueva instancia del servicio Web PubSub. Los caracteres válidos son a-z, A-Z, 0-9 y -.
    Suscripción Su suscripción Suscripción de Azure en la que se va a crear esta instancia del servicio Web PubSub.
    Grupo de recursos myResourceGroup Nombre del grupo de recursos nuevo en el que se va a crear la instancia del servicio Web PubSub.
    Ubicación Oeste de EE. UU. Seleccione una región cerca de usted.
    Plan de tarifa Gratuito Pruebe el servicio Azure Web PubSub de forma gratuita. Más información sobre los planes de tarifa del servicio Azure Web PubSub.
    Recuento de unidades - El recuento de unidades especifica cuántas conexiones puede aceptar la instancia del servicio Web PubSub. Cada unidad admite 1000 conexiones simultáneas como máximo. Solo es configurable en el nivel Estándar.

    Screenshot of creating the Azure Web PubSub instance in portal.

  4. Seleccione Crear para empezar a implementar la instancia del servicio Web PubSub.

Creación y ejecución locales de las funciones

  1. Asegúrese de que Azure Functions Core Tools está instalado. Ahora, cree un directorio vacío para el proyecto. Ejecute el comando en este directorio de trabajo. Use una de las opciones especificadas a continuación.

    func init --worker-runtime javascript --model V4
    
  2. Siga los pasos para instalar Microsoft.Azure.WebJobs.Extensions.WebPubSub.

    Confirme o actualice host.jsonextensionBundle a la versión 4.* o posterior para obtener compatibilidad con Web PubSub. Para actualizar , abra el archivo en el host.jsoneditor y reemplace la extensión de versión existenteBundle a la versión 4.* o posterior.

    {
        "extensionBundle": {
            "id": "Microsoft.Azure.Functions.ExtensionBundle",
            "version": "[4.*, 5.0.0)"
        }
    }
    
  3. Cree una función index para leer y hospedar una página web estática para los clientes.

    func new -n index -t HttpTrigger
    
    • Actualice src/functions/index.js y copie los siguientes 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. Cree una función negotiate para ayudar a los clientes a obtener la dirección URL de conexión del servicio con el token de acceso.

    func new -n negotiate -t HttpTrigger
    
    • Actualice src/functions/negotiate.js y copie los siguientes 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. Cree una función notification para generar notificaciones con TimerTrigger.

    func new -n notification -t TimerTrigger
    
    • Actualice src/functions/notification.js y copie los siguientes 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. Agregue la página única del cliente index.html en la carpeta raíz del proyecto y copie el contenido.

    <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. Configuración y ejecución de la aplicación Azure Function

    • En el explorador, abra Azure Portal y confirme que la instancia del servicio Azure Web PubSub que ha implementado anteriormente se creó correctamente. Vaya a la instancia.
    • Seleccione Claves y copie la cadena de conexión.

    Screenshot of copying the Web PubSub connection string.

    Ejecute el comando en la carpeta de funciones para establecer la cadena de conexión del servicio. Reemplace <connection-string> por su valor si fuera necesario.

    func settings add WebPubSubConnectionString "<connection-string>"
    

    Nota

    TimerTrigger usado en el ejemplo tiene dependencia de Azure Storage, pero puede usar el emulador de almacenamiento local cuando la función se ejecuta localmente. Si se produce un error como There was an error performing a read operation on the Blob Storage Secret Repository. Please ensure the 'AzureWebJobsStorage' connection string is valid., tendrá que descargar y habilitar el emulador de Storage.

    Ya puede ejecutar la función local mediante el comando siguiente.

    func start --port 7071
    

    Y al comprobar los registros en ejecución, puede visitar la página estática del host local visitando: http://localhost:7071/api/index.

    Nota:

    Algunos exploradores redirigirán automáticamente a https, que lleva a una dirección URL incorrecta. Sugiera usar Edge y compruebe la dirección URL si la representación no se ha realizado correctamente.

Implementación de una aplicación de funciones en Azure

Antes de poder implementar el código de la función en Azure, debe crear tres recursos:

  • Un grupo de recursos, que es un contenedor lógico de recursos relacionados.
  • Una cuenta de almacenamiento, que se usa para mantener el estado y otra información sobre sus funciones.
  • Una aplicación de funciones, que proporciona el entorno para ejecutar el código de función. Una aplicación de funciones se asigna a un proyecto de función local y le permite agrupar funciones como una unidad lógica, lo que facilita la administración, la implementación y el uso compartido de recursos.

Utilice los comandos siguientes para crear los elementos.

  1. Inicie de sesión en Azure:

    az login
    
  2. Cree un grupo de recursos. O bien, utilice el grupo de recursos del servicio Azure Web PubSub para omitir esta acción:

    az group create -n WebPubSubFunction -l <REGION>
    
  3. Cree una cuenta de almacenamiento de uso general en el grupo de recursos y la región:

    az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
    
  4. Cree la aplicación de funciones en 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>
    

    Nota

    Consulte la documentación de versiones en tiempo de ejecución de Azure Functions para establecer el parámetro --runtime-version al valor compatible.

  5. Implemente el proyecto de función en Azure:

    Una vez creada la aplicación de funciones en Azure, ya está listo para implementar el proyecto de funciones locales mediante el comando func azure functionapp publish .

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

    Nota:

    Aquí vamos a implementar la configuración local local.settings.json junto con el parámetro del comando --publish-local-settings. Si usa el Emulador de Microsoft Azure Storage, puede escribir no para omitir la sobreescritura de este valor en Azure siguiendo el mensaje: App setting AzureWebJobsStorage is different between azure and local.settings.json, Would you like to overwrite value in azure? [yes/no/show]. Además, puede actualizar la configuración de la aplicación de funciones en Azure Portal>Configuración>Configuración.

  6. Ahora puede comprobar el sitio desde Azure Function App; para hacerlo, vaya a la dirección URL: https://<FUNCIONAPP_NAME>.azurewebsites.net/api/index.

Limpieza de recursos

Si no va a seguir usando esta aplicación, siga los pasos que se indican a continuación para eliminar todos los recursos creados por este documento, con el fin de que no se le apliquen cargos:

  1. En Azure Portal, seleccione Grupos de recursos en el extremo izquierdo y luego seleccione el grupo de recursos que creó. Use el cuadro de búsqueda para buscar el grupo de recursos por su nombre en su lugar.

  2. En la ventana que se abrirá, seleccione el grupo de recursos y luego seleccione Eliminar grupo de recursos.

  3. En la nueva ventana, escriba el nombre del grupo de recursos que desea eliminar y, después, seleccione Eliminar.

Pasos siguientes

En este inicio rápido, ha aprendido a ejecutar una aplicación de chat sin servidor. Ahora, puede empezar a crear su propia aplicación.