O Sertão será Cloud

Dominando o Azure Web PubSub com Azure Functions e TypeScript

Bem-vindo ao quinto capítulo da nossa série emocionante sobre como integrar Azure Functions com serviços do Azure utilizando os poderosos, um dos pattern mais incriveis! Já exploramos como conectar a todos os serviços do Azure Storage e Azure Key Vault. Agora, prepare-se para mergulhar no fascinante mundo do Azure Web PubSub! 🌐

O que é o Azure Web PubSub?

O Azure Web PubSub é um serviço gerenciado da Microsoft Azure que facilita a criação de aplicativos em tempo real que requerem comunicação bidirecional em grande escala. Ele é projetado para permitir que desenvolvedores implementem facilmente funcionalidades de mensagens em tempo real, como chats, notificações, atualizações de dados ao vivo e colaboração em tempo real. Aqui estão alguns dos principais recursos e usos do Azure Web PubSub:

Principais Recursos

  1. Comunicação Bidirecional em Tempo Real: Permite que clientes e servidores troquem mensagens em tempo real de forma eficiente.
  2. Suporte a Protocolos WebSockets: Utiliza o protocolo WebSocket para comunicação eficiente e de baixa latência.
  3. Escalabilidade: Pode suportar um grande número de conexões simultâneas, facilitando a construção de aplicativos de alta escalabilidade.
  4. Autenticação e Autorização: Integra-se com Azure Active Directory e outros serviços de autenticação para garantir que apenas usuários autorizados possam acessar e enviar mensagens.
  5. Mensagens Direcionadas: Suporta o envio de mensagens para grupos específicos de usuários ou para todos os usuários conectados.
  6. Integração com Outros Serviços do Azure: Pode ser facilmente integrado com outros serviços do Azure, como Azure Functions, para criar aplicativos mais complexos e reativos.

Casos de Uso

  • Aplicativos de Chat: Implementar funcionalidades de chat em tempo real em aplicativos web ou móveis.
  • Notificações em Tempo Real: Enviar notificações instantâneas para usuários sobre eventos importantes.
  • Colaboração em Tempo Real: Criar ferramentas de colaboração como editores de texto compartilhados ou plataformas de conferência online.
  • Atualizações de Dados ao Vivo: Atualizar dados ao vivo em dashboards, jogos online, ou aplicativos financeiros.

Exemplo de Arquitetura

A arquitetura de um aplicativo usando Azure Web PubSub pode incluir:

  1. Clientes: Usuários conectam-se ao serviço Web PubSub através de navegadores ou aplicativos móveis usando WebSockets.
  2. Serviço Web PubSub: Gerencia as conexões WebSocket, roteia mensagens entre clientes e integra-se com serviços back-end.
  3. Serviços Back-End: Azure Functions, Azure App Service ou outros serviços podem processar lógica de negócios e enviar mensagens para o serviço Web PubSub para serem entregues aos clientes.

Benefícios

  • Desenvolvimento Rápido: Reduz a complexidade de construir e escalar infraestrutura para comunicação em tempo real.
  • Gerenciamento de Conexões: Lida automaticamente com a escalabilidade e gerenciamento de conexões WebSocket.
  • Baixa Latência: Oferece comunicação de baixa latência necessária para aplicativos em tempo real.

Podemos afirmar que ele simplifica o processo de integração de funcionalidades de mensagens em tempo real, permitindo que desenvolvedores se concentrem mais na lógica do aplicativo e menos na infraestrutura. Tendo isso em vista, vamos integrar?

Passo 1: Configuração do Ambiente

Antes de começar, certifique-se de ter as seguintes dependências instaladas:

npm install @azure/identity @azure/web-pubsub

OBS: Caso precise ver os Passos 1 ao 3 veja o artigo anterior sobre o tema:

Como Configurar o Azure Blob Service Client Aplicando os Princípios SOLID em uma Azure Function com…

Passo 4: Arquitetura com Provedores de Credenciais

Agora, vamos criar uma fábrica para instanciar o WebPubSubServiceClient usando nosso CredentialProvider.

import { WebPubSubServiceClient } from "@azure/web-pubsub";

/**
* Factory to create instances of WebPubSubServiceClient.
*/
class WebPubSubServiceClientFactory {
private endpoint: string;
private hubName: string;
private credentialProvider: CredentialProvider;

/**
* Creates a new instance of WebPubSubServiceClientFactory.
* @param {string} endpoint - The Azure Web PubSub endpoint.
* @param {string} hubName - The Azure Web PubSub hub name.
* @param {CredentialProvider} credentialProvider - The credential provider to use.
*/
constructor(endpoint: string, hubName: string, credentialProvider: CredentialProvider) {
this.endpoint = endpoint;
this.hubName = hubName;
this.credentialProvider = credentialProvider;
}

/**
* Creates an instance of WebPubSubServiceClient.
* @returns {WebPubSubServiceClient} A configured instance of WebPubSubServiceClient.
*/
createWebPubSubServiceClient(): WebPubSubServiceClient {
const credential = this.credentialProvider.getCredential();
return new WebPubSubServiceClient(this.endpoint, credential, this.hubName);
}
}

Passo 5: Utilizando a Fábrica em uma Azure Function

Vamos integrar tudo isso em uma Azure Function, mostrando cada método de autenticação.

Exemplo 1: Azure Function com Managed Identity Atribuída ao Sistema

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { WebPubSubServiceClientFactory } from "./WebPubSubServiceClientFactory";
import { SystemAssignedManagedIdentityCredentialProvider } from "./SystemAssignedManagedIdentityCredentialProvider";

/**
* Azure Function using System Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const endpoint = process.env.AZURE_WEBPUBSUB_HOST;
const hubName = "chathub";
const credentialProvider = new SystemAssignedManagedIdentityCredentialProvider();
const serviceClientFactory = new WebPubSubServiceClientFactory(endpoint, hubName, credentialProvider);
const serviceClient = serviceClientFactory.createWebPubSubServiceClient();
// Use the serviceClient for Web PubSub operations
context.res = {
body: "Azure Function using System Assigned Managed Identity for Access to Web PubSub"
};
};

export default httpTrigger;

Exemplo 2: Azure Function com Managed Identity Atribuída ao Usuário

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { WebPubSubServiceClientFactory } from "./WebPubSubServiceClientFactory";
import { UserAssignedManagedIdentityCredentialProvider } from "./UserAssignedManagedIdentityCredentialProvider";

/**
* Azure Function using User Assigned Managed Identity.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const endpoint = process.env.AZURE_WEBPUBSUB_HOST;
const hubName = "<hub>";
const clientId = process.env.AZURE_WEBPUBSUB_CLIENTID;
const credentialProvider = new UserAssignedManagedIdentityCredentialProvider(clientId);
const serviceClientFactory = new WebPubSubServiceClientFactory(endpoint, hubName, credentialProvider);

const serviceClient = serviceClientFactory.createWebPubSubServiceClient();
// Use the serviceClient for Web PubSub operations
context.res = {
body: "Azure Function using User Assigned Managed Identity for Access to Web PubSub"
};
};

export default httpTrigger;

Exemplo 3: Azure Function com Service Principal

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import { WebPubSubServiceClientFactory } from "./WebPubSubServiceClientFactory";
import { ServicePrincipalCredentialProvider } from "./ServicePrincipalCredentialProvider";

/**
* Azure Function using Service Principal.
* @param {Context} context - The function context.
* @param {HttpRequest} req - The HTTP request.
* @returns {Promise<void>} A promise that resolves when the function is complete.
*/
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
const endpoint = process.env.AZURE_WEBPUBSUB_HOST;
const hubName = "chathub";
const tenantId = process.env.AZURE_WEBPUBSUB_TENANTID;
const clientId = process.env.AZURE_WEBPUBSUB_CLIENTID;
const clientSecret = process.env.AZURE_WEBPUBSUB_CLIENTSECRET;
const credentialProvider = new ServicePrincipalCredentialProvider(tenantId, clientId, clientSecret);
const serviceClientFactory = new WebPubSubServiceClientFactory(endpoint, hubName, credentialProvider);

const serviceClient = serviceClientFactory.createWebPubSubServiceClient();
// Use the serviceClient for Web PubSub operations
context.res = {
body: "Azure Function using Service Principal for Access to Web PubSub"
};
};

export default httpTrigger;

Conclusão

🎉 Você acabou de aprender como configurar Azure Functions para acessar o Azure Web PubSub utilizando métodos de autenticação variados e aplicando as melhores práticas! Nossa abordagem modular e escalável torna a manutenção do código mais fácil e eficiente.

Referências

Início Rápido – Criar uma conexão de serviço no aplicativo de funções por meio do portal do Azure