Biblioteca de clientes do Barramento de Serviço do Azure para JavaScript – versão 7.9.5

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

Usar a biblioteca @azure/service-bus de clientes 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:

OBSERVAÇÃO: se você estiver usando a versão 1.1.10 ou inferior e quiser migrar para a versão mais recente deste pacote, examine 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

Pré-requisitos

Configurar TypeScript

Os usuários do TypeScript precisam ter definições de tipo de nó 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 será 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

Agrupar com o Webpack

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

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

em seguida, adicione o seguinte à sua 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"),
+    },
   },

Agrupando com rollup

Se você estiver usando o pacote cumulativo 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 dá suporte a alguma API JavaScript usada por essa biblioteca do SDK, portanto, você precisa fornecer polyfills para eles. Consulte o exemplo de React Native do Messaging com 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 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 usa 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.

const { ServiceBusClient } = require("@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 Identidade do Azure.

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

const { ServiceBusClient } = require("@azure/service-bus");
const { DefaultAzureCredential } = require("@azure/identity");

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 para 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

Principais conceitos

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

  • Filas: permite enviar e receber mensagens. Geralmente 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 do SDK:

Observe que as Filas, Tópicos e Assinaturas devem ser criadas antes de usar essa biblioteca.

Exemplos

As seções a seguir fornecem snippets 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ê poderá obter um ServiceBusSender usando o método createSender que pode ser usado para enviar mensagens.

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 .

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

Há 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 conforme são recebidas.

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

Você pode usar esse receptor de uma das três 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.

const myMessages = await receiver.receiveMessages(10);

Assinar usando um manipulador de mensagens

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

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

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

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

Resolver uma mensagem

Depois de receber uma mensagem, você poderá chamar completeMessage(), deferMessage()abandonMessage()ou deadLetterMessage() no receptor 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 sub-fila. Cada fila ou assinatura tem sua própria fila de mensagens mortas. Filas de mensagens mortas armazenam mensagens que foram explicitamente mortas (via receiver.deadLetterMessage()) ou mensagens que excederam sua contagem máxima de entrega.

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

// 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 que demonstram filas de mensagens mortas mais detalhadamente:

Enviar mensagens usando sessões

O uso de sessões exige 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.

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 exige 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 de 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, o receptor tem acesso exclusivo a ela.

Para abrir e bloquear uma sessão, use uma instância do 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 uma 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 receiveMode não for fornecido nas opções, ele usará como padrão o modo "peekLock". Você também pode resolver as mensagens recebidas no modo "peekLock".

Depois que o receptor for criado, você poderá usar escolher entre três maneiras de receber mensagens:

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

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 semelhantes 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 obter mais informações, consulte aqui.

// 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);

await serviceBusAdministrationClient.deleteQueue(queueName);

Solução de problemas

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 do AMQP

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

Registro em log

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 mensagens (que consome muito espaço em 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 ambiente da DEBUG seguinte maneira:
export DEBUG=azure:service-bus:error,azure:core-amqp:error,rhea-promise:error,rhea:events,rhea:frames,rhea:io,rhea:flow

Registrando em log em um arquivo

  1. Definir a DEBUG variável de ambiente conforme 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 registro em 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 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
    

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.

Contribuição

Se você quiser contribuir com essa biblioteca, leia o guia de contribuição para saber como criar e testar o código.

Impressões