O Sertão será Cloud

Mastering Azure Web PubSub with Azure Functions and TypeScript

Welcome to the fifth chapter of our exciting series on integrating Azure Functions with Azure services using the powerful, one of the most incredible patterns! We’ve already explored how to connect to all Azure Storage and Azure Key Vault services. Now, get ready to dive into the fascinating world of Azure Web PubSub! 🌐

What is Azure Web PubSub?

Azure Web PubSub is a managed service from Microsoft Azure that facilitates the creation of real-time applications requiring large-scale bidirectional communication. It is designed to enable developers to easily implement real-time messaging functionalities such as chats, notifications, live data updates, and real-time collaboration. Here are some of the key features and uses of Azure Web PubSub:

Key Features

  1. Bidirectional Real-Time Communication: Enables clients and servers to exchange messages in real-time efficiently.
  2. WebSocket Protocol Support: Uses the WebSocket protocol for efficient and low-latency communication.
  3. Scalability: Can support a large number of concurrent connections, facilitating the development of highly scalable applications.
  4. Authentication and Authorization: Integrates with Azure Active Directory and other authentication services to ensure that only authorized users can access and send messages.
  5. Targeted Messaging: Supports sending messages to specific groups of users or to all connected users.
  6. Integration with Other Azure Services: Easily integrates with other Azure services such as Azure Functions to create more complex and reactive applications.

Use Cases

  • 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.

Benefits

  • 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.

We can say that it simplifies the process of integrating real-time messaging functionalities, allowing developers to focus more on application logic and less on infrastructure. With that in mind, shall we integrate?

Step 1: Environment Setup

Before you begin, make sure you have the following dependencies installed:

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

Note: If you need to review Steps 1 to 3, please refer to the previous article on the topic.

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

Step 4: Architecture with Credential Providers

Now, let’s create a factory to instantiate the WebPubSubServiceClient using our 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);
}
}

Step 5: Using the Factory in an Azure Function

Let’s integrate all of this into an Azure Function, showcasing each authentication method.

Example 1: Azure Function with System-Assigned Managed Identity

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;

Example 2: Azure Function with User-Assigned Managed Identity

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;

Example 3: Azure Function with 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;

Conclusion

🎉 You’ve just learned how to configure Azure Functions to access Azure Web PubSub using various authentication methods and applying best practices! Our modular and scalable approach makes code maintenance easier and more efficient.

References

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