Barramento de Serviço do Azure client library for JavaScript - version 7.10.0

O Barramento de Serviço do Azure é um serviço de mensagens em nuvem altamente confiável da Microsoft.

Use a biblioteca @azure/service-bus de cliente em seu aplicativo para

  • Enviar mensagens para uma Fila ou Tópico do Barramento de Serviço do Azure
  • Receber mensagens de uma Fila ou Assinatura do Barramento de Serviço do Azure
  • Criar/Obter/Excluir/Atualizar/Listar Filas/Tópicos/Assinaturas/Regras em um namespace do Barramento de Serviço do Azure.

Recursos para a @azure/service-bus versão 7:

Links principais:

NOTA: Se você estiver usando a versão 1.1.10 ou inferior e quiser migrar para a versão mais recente deste pacote, consulte nosso guia de migração para migrar do Barramento de Serviço V1 para o Barramento de Serviço V7

Introdução

Instalar o pacote

Instale a versão mais recente da biblioteca de clientes do Barramento de Serviço do Azure usando o npm.

npm install @azure/service-bus

Ambientes com suporte no momento

Prerequisites

Configurar TypeScript

Os usuários do TypeScript precisam ter definições de tipo node instaladas:

npm install @types/node

Você também precisa habilitar compilerOptions.allowSyntheticDefaultImports em seu tsconfig.json. Observe que, se você tiver habilitado compilerOptions.esModuleInterop, allowSyntheticDefaultImports estará habilitado por padrão. Consulte o manual de opções do compilador do TypeScript para obter mais informações.

Pacote JavaScript

Para usar essa biblioteca de clientes no navegador, primeiro você precisa usar um empacotador. Para obter detalhes sobre como fazer isso, consulte nossa documentação de agrupamento .

Além do que está descrito lá, essa biblioteca também precisa de polifills adicionais para os seguintes módulos internos do NodeJS Core para funcionar corretamente nos navegadores:

  • buffer
  • os
  • path
  • process

Agrupamento com Webpack

Se você estiver usando o Webpack v5, poderá instalar as seguintes dependências de desenvolvimento

  • npm install --save-dev os-browserify path-browserify

em seguida, adicione o seguinte ao seu webpack.config.js

 const path = require("path");
+const webpack = require("webpack");

 module.exports = {
   entry: "./src/index.ts",
@@ -12,8 +13,21 @@ module.exports = {
       },
     ],
   },
+  plugins: [
+    new webpack.ProvidePlugin({
+      process: "process/browser",
+    }),
+    new webpack.ProvidePlugin({
+      Buffer: ["buffer", "Buffer"],
+    }),
+  ],
   resolve: {
     extensions: [".ts", ".js"],
+    fallback: {
+      buffer: require.resolve("buffer/"),
+      os: require.resolve("os-browserify"),
+      path: require.resolve("path-browserify"),
+    },
   },

Agrupamento com Rollup

Se você estiver usando o empacotador rollup, instale as dependências de desenvolvimento a seguir

  • npm install --save-dev @rollup/plugin-commonjs @rollup/plugin-inject @rollup/plugin-node-resolve

Em seguida, inclua o seguinte em seu rollup.config.js

+import nodeResolve from "@rollup/plugin-node-resolve";
+import cjs from "@rollup/plugin-commonjs";
+import shim from "rollup-plugin-shim";
+import inject from "@rollup/plugin-inject";

export default {
  // other configs
  plugins: [
+    shim({
+      fs: `export default {}`,
+      net: `export default {}`,
+      tls: `export default {}`,
+      path: `export default {}`,
+      dns: `export function resolve() { }`,
+    }),
+    nodeResolve({
+      mainFields: ["module", "browser"],
+      preferBuiltins: false,
+    }),
+    cjs(),
+    inject({
+      modules: {
+        Buffer: ["buffer", "Buffer"],
+        process: "process",
+      },
+      exclude: ["./**/package.json"],
+    }),
  ]
};

Consulte a documentação do seu empacotador favorito para obter mais informações sobre como usar polyfills.

Suporte nativo do React

Semelhante aos navegadores, o React Native não oferece suporte a algumas APIs JavaScript usadas por esta biblioteca SDK, portanto, você precisa fornecer polyfills para eles. Consulte o exemplo do Messaging React Native com a Expo para obter mais detalhes.

Autenticar o cliente

A interação com o Barramento de Serviço começa com uma instância da classe ServiceBusClient . Você pode se autenticar no Barramento de Serviço usando uma cadeia de conexão ou usando uma credencial do Azure Active Directory.

Usando uma cadeia de conexão

Esse método leva a cadeia de conexão para sua instância do Barramento de Serviço. Você pode obter a cadeia de conexão no portal do Azure.

import { ServiceBusClient } from "@azure/service-bus";

const serviceBusClient = new ServiceBusClient("<connectionString>");

Mais informações sobre esse construtor estão disponíveis na documentação da API.

Usando uma credencial do Azure Active Directory

A autenticação com o Azure Active Directory usa a biblioteca de identidades do Azure.

O exemplo a seguir usa o DefaultAzureCredential, um dos muitos provedores de credenciais disponíveis na @azure/identity biblioteca.

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

OBSERVAÇÃO: se você estiver usando sua própria implementação da TokenCredential interface no AAD, defina os "escopos" do barramento de serviço como o seguinte para obter o token apropriado:

["https://servicebus.azure.net//user_impersonation"];

Mais informações sobre esse construtor estão disponíveis na documentação da API

Conceitos principais

Depois de inicializar um ServiceBusClient, você pode interagir com esses recursos em um Namespace do Barramento de Serviço:

  • Filas: Permite enviar e receber mensagens. Frequentemente usado para comunicação ponto a ponto.
  • Tópicos: ao contrário das filas, os tópicos são mais adequados para cenários de publicação/assinatura. Um tópico pode ser enviado, mas requer uma assinatura, da qual pode haver várias em paralelo, para consumir.
  • Assinaturas: o mecanismo a ser consumido de um tópico. Cada assinatura é independente e recebe uma cópia de cada mensagem enviada ao tópico. Regras e filtros podem ser usados para personalizar quais mensagens são recebidas por uma assinatura específica.

Para obter mais informações sobre esses recursos, consulte O que é o Barramento de Serviço do Azure?.

Para interagir com esses recursos, deve-se estar familiarizado com os seguintes conceitos de SDK:

Observe que as filas, tópicos e assinaturas devem ser criados antes de usar esta biblioteca.

Examples

As seções a seguir fornecem trechos de código que abrangem algumas das tarefas comuns usando o Barramento de Serviço do Azure

Enviar mensagens

Depois de criar uma instância de uma ServiceBusClient classe, você pode obter um ServiceBusSender usando o método createSender que pode ser usado para enviar mensagens.

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const sender = serviceBusClient.createSender("my-queue");

const messages = [
  { body: "Albert Einstein" },
  { body: "Werner Heisenberg" },
  { body: "Marie Curie" },
  { body: "Steven Hawking" },
  { body: "Isaac Newton" },
  { body: "Niels Bohr" },
  { body: "Michael Faraday" },
  { body: "Galileo Galilei" },
  { body: "Johannes Kepler" },
  { body: "Nikolaus Kopernikus" },
];

// sending a single message
await sender.sendMessages(messages[0]);

// sending multiple messages in a single call
// this will fail if the messages cannot fit in a batch
await sender.sendMessages(messages);

// Sends multiple messages using one or more ServiceBusMessageBatch objects as required
let batch = await sender.createMessageBatch();

for (let i = 0; i < messages.length; i++) {
  const message = messages[i];
  if (!batch.tryAddMessage(message)) {
    // Send the current batch as it is full and create a new one
    await sender.sendMessages(batch);
    batch = await sender.createMessageBatch();

    if (!batch.tryAddMessage(messages[i])) {
      throw new Error("Message too big to fit in a batch");
    }
  }
}
// Send the batch
await sender.sendMessages(batch);

Receber mensagens

Depois de criar uma instância de uma ServiceBusClient classe, você pode obter um ServiceBusReceiver usando o método createReceiver .

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const receiver = serviceBusClient.createReceiver("my-queue");

Existem dois receiveModes disponíveis.

  • "peekLock" - No modo peekLock, o receptor tem um bloqueio na mensagem pela duração especificada na fila.
  • "receiveAndDelete" – No modo receiveAndDelete, as mensagens são excluídas do Barramento de Serviço à medida que são recebidas.

Se o receiveMode não for fornecido nas opções, o padrão será o modo "peekLock". Você também pode liquidar as mensagens recebidas no modo "peekLock".

Você pode usar esse receptor de uma das 3 maneiras de receber mensagens:

Obter uma matriz de mensagens

Use a função receiveMessages , que retorna uma promessa que é resolvida para uma matriz de mensagens.

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const receiver = serviceBusClient.createReceiver("my-queue");

const myMessages = await receiver.receiveMessages(10);

Inscrever-se usando um manipulador de mensagens

Use o método subscribe para configurar manipuladores de mensagens e executá-lo pelo tempo que for necessário.

Quando terminar, ligue receiver.close() para parar de receber mais mensagens.

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const receiver = serviceBusClient.createReceiver("my-queue");

const myMessageHandler = async (message) => {
  // your code here
  console.log(`message.body: ${message.body}`);
};
const myErrorHandler = async (args) => {
  console.log(
    `Error occurred with ${args.entityPath} within ${args.fullyQualifiedNamespace}: `,
    args.error,
  );
};
receiver.subscribe({
  processMessage: myMessageHandler,
  processError: myErrorHandler,
});

Usar iterador assíncrono

Use o getMessageIterator para obter um iterador assíncrono sobre mensagens

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const receiver = serviceBusClient.createReceiver("my-queue");

for await (const message of receiver.getMessageIterator()) {
  // your code here
}

Liquidar uma mensagem

Depois de receber uma mensagem, você pode ligar para completeMessage(), abandonMessage(), deferMessage() ou deadLetterMessage() no destinatário com base em como deseja resolver a mensagem.

Para saber mais, leia Resolvendo mensagens recebidas

Filas de mensagens mortas

A fila de mensagens mortas é uma subfila. Cada fila ou assinatura tem sua própria fila de mensagens mortas. As filas de mensagens mortas armazenam mensagens que foram explicitamente enviadas (via receiver.deadLetterMessage()) ou mensagens que excederam sua contagem máxima de entrega.

A criação de um receptor para uma subfila de mensagens mortas é semelhante à criação de um receptor para uma assinatura ou fila:

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

// To receive from a queue's dead letter sub-queue
const deadLetterReceiverForQueue = serviceBusClient.createReceiver("queue", {
  subQueueType: "deadLetter",
});

// To receive from a subscription's dead letter sub-queue
const deadLetterReceiverForSubscription = serviceBusClient.createReceiver("topic", "subscription", {
  subQueueType: "deadLetter",
});

// Dead letter receivers work like any other receiver connected to a queue
// ex:
const messages = await deadLetterReceiverForQueue.receiveMessages(5);

for (const message of messages) {
  console.log(`Dead lettered message: ${message.body}`);
}

Exemplos completos demonstrando filas de mensagens mortas mais detalhadamente:

Enviar mensagens usando Sessões

O uso de sessões requer que você crie uma Fila ou Assinatura habilitada para sessão. Você pode ler mais sobre como configurar esse recurso no portal aqui.

Para enviar mensagens para uma sessão, use o ServiceBusClient para criar um remetente usando createSender.

Ao enviar a mensagem, defina a sessionId propriedade na mensagem para garantir que sua mensagem chegue à sessão correta.

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

const sender = serviceBusClient.createSender("my-session-queue");
await sender.sendMessages({
  body: "my-message-body",
  sessionId: "my-session",
});

Você pode ler mais sobre como as sessões funcionam aqui.

Receber mensagens de Sessões

O uso de sessões requer que você crie uma Fila ou Assinatura habilitada para sessão. Você pode ler mais sobre como configurar esse recurso no portal aqui.

Ao contrário das filas ou assinaturas não habilitadas para sessão, apenas um único receptor pode ler de uma sessão a qualquer momento. Isso é imposto bloqueando uma sessão, que é tratada pelo Barramento de Serviço. Conceitualmente, isso é semelhante a como o bloqueio de mensagens funciona ao usar peekLock o modo - quando uma mensagem (ou sessão) é bloqueada, seu destinatário tem acesso exclusivo a ela.

Para abrir e bloquear uma sessão, use uma instância de ServiceBusClient para criar um SessionReceiver.

Há duas maneiras de escolher qual sessão abrir:

  1. Especifique um sessionId, que bloqueia uma sessão nomeada.

    const receiver = await serviceBusClient.acceptSession("my-session-queue", "my-session");
    
  2. Não especifique um ID de sessão. Nesse caso, o Barramento de Serviço encontrará a próxima sessão disponível que ainda não está bloqueada.

    const receiver = await serviceBusClient.acceptNextSession("my-session-queue");
    

    Você pode encontrar o nome da sessão por meio da sessionId propriedade no SessionReceiver. Se o receiveMode não for fornecido nas opções, o padrão será o modo "peekLock". Você também pode liquidar as mensagens recebidas no modo "peekLock".

Uma vez que o receptor é criado, você pode escolher entre 3 maneiras de receber mensagens:

Você pode ler mais sobre como as sessões funcionam aqui.

Listar sessões de mensagens

Para descobrir quais sessões têm mensagens ativas ou estado de sessão em uma fila ou assinatura, use listMessageSessions():

import { DefaultAzureCredential } from "@azure/identity";
import { ServiceBusClient } from "@azure/service-bus";

const fullyQualifiedNamespace = "<name-of-service-bus-namespace>.servicebus.windows.net";
const credential = new DefaultAzureCredential();
const serviceBusClient = new ServiceBusClient(fullyQualifiedNamespace, credential);

// List all sessions with active messages or session state in a queue
for await (const sessionId of serviceBusClient.listMessageSessions("my-session-queue")) {
  console.log("Session ID:", sessionId);
}

// List sessions in a subscription
for await (const sessionId of serviceBusClient.listMessageSessions("my-topic", "my-subscription")) {
  console.log("Session ID:", sessionId);
}

// List only sessions whose stored session state was set or updated in the last seven days
const sessionStateUpdatedAfter = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
for await (const sessionId of serviceBusClient.listMessageSessions("my-session-queue", {
  sessionStateUpdatedAfter,
})) {
  console.log("Recently updated session ID:", sessionId);
}

Gerenciar recursos de um namespace do barramento de serviço

ServiceBusAdministrationClient permite gerenciar um namespace com operações CRUD nas entidades (filas, tópicos e assinaturas) e nas regras de uma assinatura.

  • Dá suporte à autenticação com uma cadeia de conexão do barramento de serviço, bem como com as credenciais do AAD de @azure/identity semelhante ao ServiceBusClient.

Observação: o Barramento de Serviço ainda não dá suporte à configuração de regras CORS para namespaces, portanto ServiceBusAdministrationClient , não funcionará no navegador sem desabilitar a segurança da Web. Para mais informações, consulte aqui.

import { ServiceBusAdministrationClient } from "@azure/service-bus";

const queueName = "my-session-queue";

// Get the connection string from the portal
// OR
// use the token credential overload, provide the host name of your Service Bus instance and the AAD credentials from the @azure/identity library
const serviceBusAdministrationClient = new ServiceBusAdministrationClient("<connectionString>");

// Similarly, you can create topics and subscriptions as well.
const createQueueResponse = await serviceBusAdministrationClient.createQueue(queueName);
console.log("Created queue with name - ", createQueueResponse.name);

const queueRuntimeProperties =
  await serviceBusAdministrationClient.getQueueRuntimeProperties(queueName);
console.log(`Number of messages in the queue = ${queueRuntimeProperties.totalMessageCount}`);

// Topic runtime properties additionally report the total number of SQL and correlation filters
// across all of the topic's subscriptions. These counts are served by the 2024-05 service API
// version and later; on an older version they are `undefined`.
const topicName = "my-topic";
const subscriptionName = "my-subscription";
await serviceBusAdministrationClient.createTopic(topicName);
// A new subscription carries a default rule with a SQL TrueFilter. Adding a correlation rule
// gives the topic one of each, so the counts below aggregate across the subscription's rules.
await serviceBusAdministrationClient.createSubscription(topicName, subscriptionName);
await serviceBusAdministrationClient.createRule(
  topicName,
  subscriptionName,
  "my-correlation-rule",
  { correlationId: "my-correlation-id" },
);
const topicRuntimeProperties =
  await serviceBusAdministrationClient.getTopicRuntimeProperties(topicName);
console.log(`SQL filter count = ${topicRuntimeProperties.sqlFilterCount}`);
console.log(`Correlation filter count = ${topicRuntimeProperties.correlationFilterCount}`);

await serviceBusAdministrationClient.deleteTopic(topicName);
await serviceBusAdministrationClient.deleteQueue(queueName);

Troubleshooting

Aqui estão algumas etapas iniciais para começar a diagnosticar problemas. Para obter mais informações, consulte o Guia de Solução de Problemas do Barramento de Serviço.

Dependências amqp

A biblioteca do Barramento de Serviço depende da biblioteca rhea-promise para gerenciar conexões, enviar e receber mensagens pelo protocolo AMQP .

Logging

Você pode definir a variável de ambiente a seguir para obter os logs de depuração ao usar essa biblioteca.

  • Obtendo logs de depuração do SDK do Barramento de Serviço
export DEBUG=azure*
  • Obtendo logs de depuração do SDK do Barramento de Serviço e da biblioteca de nível de protocolo.
export DEBUG=azure*,rhea*
  • Se você não estiver interessado em exibir a transformação de mensagem (que consome muito espaço no console/disco), poderá definir a DEBUG variável de ambiente da seguinte maneira:
export DEBUG=azure*,rhea*,-rhea:raw,-rhea:message,-azure:core-amqp:datatransformer
  • Se você estiver interessado apenas em erros, poderá definir a variável de DEBUG ambiente da seguinte maneira:
export DEBUG=azure:service-bus:error,azure:core-amqp:error,rhea-promise:error,rhea:events,rhea:frames,rhea:io,rhea:flow

Fazer logon em um arquivo

  1. Defina a variável de DEBUG ambiente conforme mostrado acima
  2. Execute o script de teste da seguinte maneira:
  • As instruções de registro em log do script de teste vão para out.log e as instruções de registro em log do sdk vão para debug.log.
    node your-test-script.js > out.log 2>debug.log
    
  • As instruções de registro em log do script de teste e do sdk vão para o mesmo arquivo out.log redirecionando stderr para stdout (&1) e, em seguida, redirecione stdout para um arquivo:
    node your-test-script.js >out.log 2>&1
    
  • As instruções de registro em log do script de teste e do sdk vão para o mesmo arquivo out.log.
      node your-test-script.js &> out.log
    

Próximas Etapas 

Dê uma olhada no diretório de exemplos para obter exemplos detalhados sobre como usar essa biblioteca para enviar e receber mensagens de/para Filas, Tópicos e Assinaturas do Barramento de Serviço.

Contributing

Se você quiser contribuir para esta biblioteca, por favor leia o guia contribuição para saber mais sobre como construir e testar o código.