Azure Service Bus client library for JavaScript - version 7.10.0

O Barramento de Serviço do Azure é um serviço de mensagens na 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 Subscrição do Barramento de Serviço do Azure
  • Create/Get/Delete/Update/List Queues/Topics/Subscriptions/Rules em um namespace do Barramento de Serviço do Azure.

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

Ligações principais:

NOTA: Se estiver a utilizar a versão 1.1.10 ou inferior e pretender migrar para a versão mais recente deste pacote, consulte o nosso guia de migração para mudar do Service Bus V1 para o Service Bus V7

Introdução

Instale o pacote

Instale a versão mais recente para a biblioteca de cliente do Azure Service Bus usando npm.

npm install @azure/service-bus

Ambientes atualmente suportados

Prerequisites

Configurar o TypeScript

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

npm install @types/node

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

Pacote JavaScript

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

Além do que é descrito lá, essa biblioteca também precisa de polipreenchimentos adicionais para os seguintes módulos internos do núcleo NodeJS para funcionar corretamente nos navegadores:

  • buffer
  • os
  • path
  • process

Agregação 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"),
+    },
   },

Agregação com Rollup

Se você estiver usando o empacotador Rollup, instale as seguintes dependências de desenvolvimento

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

Em seguida, inclua o seguinte no 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 bundler favorito para obter mais informações sobre o uso de polyfills.

Suporte nativo do React

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

Autenticar o cliente

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

Usando uma string de conexão

Esse método leva a cadeia de conexão para sua instância do Service Bus. Você pode obter a string 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 Ative Directory

A autenticação com o Azure Ative Directory usa a biblioteca de Identidades do Azure.

O exemplo abaixo 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);

NOTA: Se você estiver usando sua própria implementação da interface em relação ao TokenCredential AAD, defina os "escopos" para o 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 Service Bus:

  • Filas: Permite enviar e receber mensagens. Muitas vezes usado para comunicação ponto-a-ponto.
  • Tópicos: Ao contrário de 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ários em paralelo, para consumir.
  • Assinaturas: o mecanismo para consumir a partir de um tópico. Cada assinatura é independente e recebe uma cópia de cada mensagem enviada para o tópico. As 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:

Tenha em atenção que as Filas, Tópicos e Subscrições devem ser criadas antes de utilizar 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 você pode usar 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 uma 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");

Há dois receiveModes disponíveis.

  • "peekLock" - No modo peekLock, o recetor tem um bloqueio na mensagem para a duração especificada na fila.
  • "receiveAndDelete" - No modo receiveAndDelete, as mensagens são excluídas do Service Bus à 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 este recetor em uma das 3 maneiras de receber mensagens:

Obter uma série 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 o tempo que você precisar.

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
}

Resolver uma mensagem

Depois de receber uma mensagem, completeMessage() você pode ligar abandonMessage()para , deferMessage()ou deadLetterMessage() para o recetor com base em como você deseja liquidar a mensagem.

Para saber mais, leia Liquidando mensagens recebidas

Filas de mensagens não entregues

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

Criar um recetor para uma subfila de letra morta é semelhante a criar um recetor 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}`);
}

Amostras completas demonstrando filas de letras 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 a 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 recetor pode ler de uma sessão a qualquer momento. Isso é imposto bloqueando uma sessão, que é manipulada pelo Service Bus. Conceitualmente, isso é semelhante a como o bloqueio de mensagens funciona ao usar peekLock o modo - quando uma mensagem (ou sessão) é bloqueada, seu recetor 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 Service Bus 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 através 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 recetor é 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 as sessões que têm mensagens ativas ou estado de sessão numa fila ou subscrição, utilize 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.

  • Suporta autenticação com uma cadeia de conexão de barramento de serviço, @azure/identitybem como com as credenciais do AAD semelhantes ServiceBusClient ao .

Nota: O Service Bus ainda não suporta a definição de regras CORS para namespaces, portanto ServiceBusAdministrationClient , não funcionará no navegador sem desativar 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 alguns passos iniciais para começar a diagnosticar problemas. Para obter mais informações, consulte o Guia de solução de problemas do Service Bus.

Dependências AMQP

A biblioteca do Service Bus depende da biblioteca rhea-promise para gerenciar conexões, enviar e receber mensagens pelo protocolo AMQP .

Logging

Pode definir a seguinte variável de ambiente para obter os registos de depuração ao usar esta biblioteca.

  • Obtendo logs de depuração do SDK do Service Bus
export DEBUG=azure*
  • Obter logs de depuração do SDK do Service Bus e da biblioteca de nível de protocolo.
export DEBUG=azure*,rhea*
  • Se você não estiver interessado em visualizar a transformação de mensagem (que consome muito espaço no console/disco), então você pode 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, então você pode 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

Registar num ficheiro

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

Passos seguintes

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 Service Bus.

Contributing

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