Azure Service Bus トピックへのメッセージ送信とトピックのサブスクリプションからのメッセージ受信 (JavaScript)
このチュートリアルでは、次の手順を実行します。
- Azure Portal を使用して Service Bus 名前空間を作成する。
- Azure Portal を使用して Service Bus トピックを作成する。
- そのトピックに対する Service Bus サブスクリプションを Azure Portal で作成する。
- 次のことを行うための JavaScript アプリケーションを @azure/service-bus パッケージを使って作成する。
- メッセージのセットをトピックに送信する。
- サブスクリプションからそれらのメッセージを受信する。
注意
このクイック スタートでは、メッセージのバッチを Service Bus トピックに送信し、それらのメッセージをトピックのサブスクリプションから受信するという単純なシナリオの手順を説明します。 Azure Service Bus の事前構築済みの JavaScript および TypeScript サンプルが、GitHub の Azure SDK for JavaScript リポジトリに用意されています。
前提条件
- Azure サブスクリプション。 このチュートリアルを完了するには、Azure アカウントが必要です。 MSDN のサブスクライバー特典を有効にするか、無料アカウントにサインアップしてください。
- Node.js LTS
- 「Quickstart:Azure portal を使用して Service Bus トピックとそのサブスクリプションを作成する」の手順に従ってください。 このクイックスタートで使用するサブスクリプションは 1 つだけです。
自分の Azure アカウントでこのクイックスタートを行うには、次のものが必要です。
- 開発者マシンにパスワードレス認証を提供する Azure CLI をインストールします。
- ターミナルまたはコマンド プロンプトで、
az login
を使って Azure アカウントでサインインします。 - リソースに適切なロールを追加するときは、同じアカウントを使います。
- 同じターミナルまたはコマンド プロンプトでコードを実行します。
- Service Bus 名前空間のトピックの名前とサブスクリプションを控えておきます。 コードでそれが必要になります。
Note
- このチュートリアルでは、コピーして Nodejs を使用して実行できるサンプルを扱います。 Node.js アプリケーションを作成する手順については、Node.js アプリケーションの作成と Azure Web サイトへのデプロイに関するページ、または Windows PowerShell を使用する Node.js クラウド サービスに関するページを参照してください。
Azure Portal での名前空間の作成
Azure の Service Bus メッセージング エンティティを使用するには、Azure 全体で一意となる名前を備えた名前空間を最初に作成しておく必要があります。 名前空間により、ご利用のアプリケーション内に Service Bus リソース (キュー、トピックなど) 用のスコープ コンテナーが提供されます。
名前空間を作成するには:
Azure portal にサインインします。
[すべてのサービス] ページに移動します。
左側のナビゲーション バーで、カテゴリの一覧から [統合] を選択し、[Service Bus] 上にマウス ポインターを置き、[Service Bus] タイルの [+] ボタンを選択します。
[名前空間の作成] ページの [基本] タブで、こちらの手順を実行します。
[サブスクリプション] で、名前空間を作成する Azure サブスクリプションを選択します。
[リソース グループ] で、名前空間を追加する既存のリソース グループを選択するか、新しいリソース グループを作成します。
名前空間の名前を入力します。 名前空間名は次の名前付け規則に従う必要があります。
- この名前は Azure 全体で一意である必要があります。 その名前が使用できるかどうかがすぐに自動で確認されます。
- 名前の長さは 6 ~ 50 文字である。
- この名前には、文字、数字、ハイフン "-" のみを含めることができます。
- 名前の先頭は文字、末尾は文字または数字にする必要があります。
- 名前の末尾は “-sb“ または “-mgmt“ にはできません。
[場所] で、名前空間をホストするリージョンを選択します。
[価格レベル] で、名前空間の価格レベル (Basic、Standard、Premium) を選択します。 このクイック スタートでは、 [Standard] を選択します。
重要
トピックとサブスクリプションを使用する場合は、Standard または Premium を選択してください。 Basic 価格レベルでは、トピックとサブスクリプションはサポートされていません。
[Premium] 価格レベルを選択した場合は、メッセージング ユニットの数を指定します。 Premium レベルでは、各ワークロードが分離した状態で実行されるように、CPU とメモリのレベルでリソースが分離されます。 このリソースのコンテナーをメッセージング ユニットと呼びます。 Premium 名前空間には、少なくとも 1 つのメッセージング ユニットがあります。 Service Bus の Premium 名前空間ごとに、1 個、2 個、4 個、8 個、または 16 個のメッセージング ユニットを選択できます。 詳細については、Service Bus の Premium メッセージングに関するページをご覧ください。
ページ下部にある [確認と作成] を選択します。
[確認および作成] ページで、設定を確認し、 [作成] を選択します。
リソースのデプロイが成功したら、デプロイ ページで [リソースに移動] を選択します。
Service Bus 名前空間のホーム ページが表示されます。
Azure Portal を使用したトピックの作成
[Service Bus 名前空間] ページで、左側のメニューの [トピック] を選択します。
ツール バーの [+ トピック] を選択します。
トピックの名前を入力します。 他のオプションは既定値のままにしてください。
[作成] を選択します。
トピックに対するサブスクリプションの作成
前のセクションで作成したトピックを選択します。
[Service Bus トピック] ページで、ツール バーの [+ サブスクリプション] を選択します。
[サブスクリプションの作成] ページで、次の手順に従います。
サブスクリプションの名前として「S1」と入力します。
[最大配信数] に「3」と入力します。
次に、 [作成] を選択してサブスクリプションを作成します。
Azure に対してアプリを認証する
このクイック スタートでは、Azure Service Bus に接続する 2 つの方法である、パスワードレスと接続文字列について説明します。
最初のオプションでは、Microsoft Entra ID とロールベースのアクセス制御 (RBAC) でセキュリティ プリンシパルを使用して Service Bus 名前空間に接続する方法を示します。 コードや構成ファイル、または Azure Key Vault などのセキュリティで保護されたストレージに、ハードコーディングされた接続文字列を含める心配はありません。
2 番目のオプションでは、接続文字列を使用して Service Bus 名前空間に接続する方法を示します。 Azure を初めて使用する場合は、接続文字列オプションの方が理解しやすいかもしれません。 実際のアプリケーションと運用環境では、パスワードレス オプションを使用することをお勧めします。 詳細については、「認証と承認」を参照してください。 パスワードレス認証の詳細については、概要ページを参照してください。
Microsoft Entra ユーザーにロールを割り当てる
ローカルでの開発時には、Azure Service Bus に接続するユーザー アカウントに正しいアクセス許可があることを確認してください。 メッセージを送受信するには、Azure Service Bus データ所有者ロールが必要です。 このロールを自分に割り当てるには、ユーザー アクセス管理者ロール、または Microsoft.Authorization/roleAssignments/write
アクションを含む別のロールが必要です。 Azure portal、Azure CLI、または Azure PowerShell を使用して、ユーザーに Azure RBAC ロールを割り当てることができます。 ロールの割り当てに使用できるスコープの詳細は、スコープの概要ページを参照してください。
次の例では、ユーザー アカウントに、Azure Service Bus Data Owner
ロールを割り当てます。これにより、Azure Service Bus リソースへのフル アクセスが提供されます。 実際のシナリオでは、より安全な運用環境を実現するため、最小限の特権の原則に従って、必要な最小限のアクセス許可のみをユーザーに付与します。
Azure Service Bus 用の Azure 組み込みロール
Azure Service Bus の場合、名前空間およびそれに関連するすべてのリソースの Azure portal および Azure リソース管理 API による管理は、Azure RBAC モデルを使って既に保護されています。 Azure では、Service Bus 名前空間へのアクセスを承認するための次の Azure 組み込みロールが提供されています。
- Azure Service Bus データ所有者:Service Bus 名前空間とそのエンティティ (キュー、トピック、サブスクリプション、およびフィルター) へのデータ アクセスが可能です。 このロールのメンバーは、キューまたはトピックやサブスクリプションとの間でメッセージを送受信できます。
- Azure Service Bus データ送信者: このロールを使用して、Service Bus 名前空間とそのエンティティへの送信アクセスを許可します。
- Azure Service Bus データ受信者: このロールを使用して、Service Bus 名前空間とそのエンティティへの受信アクセスを許可します。
カスタム ロールを作成する場合は、Service Bus 操作に必要な権限に関するページを参照してください。
Microsoft Entra ユーザーを Azure Service Bus 所有者ロールに追加する
Microsoft Entra ユーザー名を、Service Bus 名前空間レベルの Azure Service Bus データ所有者ロール に追加します。 これにより、ユーザー アカウントのコンテキストで実行されているアプリがキューまたはトピックにメッセージを送信し、キューまたはトピックのサブスクリプションからメッセージを受信できるようになります。
重要
ほとんどの場合、ロールの割り当てが Azure に反映されるまでの時間は 1、2 分です。 まれに、最大 8 分かかる場合があります。 初めてコードを実行したときに認証エラーを受け取る場合は、しばらく待ってから再試行してください。
Azure portal で Service Bus 名前空間ページが開いていない場合は、メイン検索バーまたは左側のナビゲーションを使用して Service Bus 名前空間を見つけます。
概要ページで、左側のメニューから [アクセス制御 (IAM)] を選択します。
[アクセス制御 (IAM)] ページで、[ロールの割り当て] タブを選びます。
上部のメニューから [+ 追加] を選択し、次に結果のドロップダウン メニューから [ロールの割り当ての追加] を選択します。
検索ボックスを使って、結果を目的のロールに絞り込みます。 この例では、
Azure Service Bus Data Owner
を検索して一致する結果を選択します。 [次へ] を選びます。[アクセスの割り当て先] で、[ユーザー、グループ、またはサービス プリンシパル] を選び、[+ メンバーの選択] を選びます。
ダイアログで、自分の Microsoft Entra ユーザー名 (通常は user@domain メール アドレス) を検索し、ダイアログの下部にある [選択] を選びます。
[レビューと割り当て] を選んで最終ページに移動し、もう一度 [レビューと割り当て] を行ってプロセスを完了します。
ノード パッケージ マネージャー (NPM) を使用してパッケージをインストールする
Service Bus の必要な npm パッケージをインストールするには、パスに
npm
を設定したコマンド プロンプトを開き、サンプルを格納するフォルダーにディレクトリを変更してから、このコマンドを実行します。次のパッケージをインストールします。
npm install @azure/service-bus @azure/identity
メッセージをトピックに送信する
次のサンプル コードは、メッセージのバッチを Service Bus トピックに送信する方法を示しています。 詳細については、コードのコメントを参照してください。
このコードで必要なパスワードレス認証をローカル コンピューターで提供するには、Azure CLI の az login
でサインインしている必要があります。
Visual Studio Code など、お好みのエディターを開きます
sendtotopic.js
というファイルを作成し、そこに以下のコードを貼り付けます。 このコードによって、トピックにメッセージが送信されます。重要
パスワードレスの資格情報は、DefaultAzureCredential で提供されます。
const { ServiceBusClient } = require("@azure/service-bus"); const { DefaultAzureCredential } = require("@azure/identity"); // Replace `<SERVICE-BUS-NAMESPACE>` with your namespace const fullyQualifiedNamespace = "<SERVICE-BUS-NAMESPACE>.servicebus.windows.net"; // Passwordless credential const credential = new DefaultAzureCredential(); const topicName = "<TOPIC NAME>"; 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" } ]; async function main() { // create a Service Bus client using the passwordless authentication to the Service Bus namespace const sbClient = new ServiceBusClient(fullyQualifiedNamespace, credential); // createSender() can also be used to create a sender for a queue. const sender = sbClient.createSender(topicName); try { // Tries to send all messages in a single batch. // Will fail if the messages cannot fit in a batch. // await sender.sendMessages(messages); // create a batch object let batch = await sender.createMessageBatch(); for (let i = 0; i < messages.length; i++) { // for each message in the array // try to add the message to the batch if (!batch.tryAddMessage(messages[i])) { // if it fails to add the message to the current batch // send the current batch as it is full await sender.sendMessages(batch); // then, create a new batch batch = await sender.createMessageBatch(); // now, add the message failed to be added to the previous batch to this batch if (!batch.tryAddMessage(messages[i])) { // if it still can't be added to the batch, the message is probably too big to fit in a batch throw new Error("Message too big to fit in a batch"); } } } // Send the last created batch of messages to the topic await sender.sendMessages(batch); console.log(`Sent a batch of messages to the topic: ${topicName}`); // Close the sender await sender.close(); } finally { await sbClient.close(); } } // call the main function main().catch((err) => { console.log("Error occurred: ", err); process.exit(1); });
<SERVICE BUS NAMESPACE CONNECTION STRING>
を Service Bus 名前空間の接続文字列に置き換えます。<TOPIC NAME>
を対象のトピックの名前に置き換えます。その後、コマンド プロンプトで次のコマンドを実行して、このファイルを実行します。
node sendtotopic.js
次の出力が表示されます。
Sent a batch of messages to the topic: mytopic
サブスクリプションからメッセージを受信する
このコードで必要なパスワードレス認証をローカル コンピューターで提供するには、Azure CLI の az login
でサインインしている必要があります。
Visual Studio Code など、お好みのエディターを開きます
receivefromsubscription.js というファイルを作成し、そこに次のコードを貼り付けます。 詳細については、コードのコメントを参照してください。
const { delay, ServiceBusClient, ServiceBusMessage } = require("@azure/service-bus"); const { DefaultAzureCredential } = require("@azure/identity"); // Replace `<SERVICE-BUS-NAMESPACE>` with your namespace const fullyQualifiedNamespace = "<SERVICE-BUS-NAMESPACE>.servicebus.windows.net"; // Passwordless credential const credential = new DefaultAzureCredential(); const topicName = "<TOPIC NAME>"; const subscriptionName = "<SUBSCRIPTION NAME>"; async function main() { // create a Service Bus client using the passwordless authentication to the Service Bus namespace const sbClient = new ServiceBusClient(fullyQualifiedNamespace, credential); // createReceiver() can also be used to create a receiver for a queue. const receiver = sbClient.createReceiver(topicName, subscriptionName); // function to handle messages const myMessageHandler = async (messageReceived) => { console.log(`Received message: ${messageReceived.body}`); }; // function to handle any errors const myErrorHandler = async (error) => { console.log(error); }; // subscribe and specify the message and error handlers receiver.subscribe({ processMessage: myMessageHandler, processError: myErrorHandler }); // Waiting long enough before closing the sender to send messages await delay(5000); await receiver.close(); await sbClient.close(); } // call the main function main().catch((err) => { console.log("Error occurred: ", err); process.exit(1); });
<SERVICE BUS NAMESPACE CONNECTION STRING>
を名前空間の接続文字列に置き換えます。<TOPIC NAME>
を対象のトピックの名前に置き換えます。<SUBSCRIPTION NAME>
をトピックのサブスクリプションの名前に置き換えます。その後、コマンド プロンプトで次のコマンドを実行して、このファイルを実行します。
node receivefromsubscription.js
次の出力が表示されます。
Received message: Albert Einstein
Received message: Werner Heisenberg
Received message: Marie Curie
Received message: Steven Hawking
Received message: Isaac Newton
Received message: Niels Bohr
Received message: Michael Faraday
Received message: Galileo Galilei
Received message: Johannes Kepler
Received message: Nikolaus Kopernikus
Azure portal で Service Bus 名前空間に移動し、下部のペインで [トピック] に切り替え、トピックを選択してそのトピックの [Service Bus トピック] ページを表示します。 このページの [メッセージ] グラフには 10 個の受信と 10 個の送信メッセージが表示されます。
アプリの送信のみを次回実行すると、[Service Bus トピック] ページには 20 個の受信メッセージ (10 件の新着) と 10 個の送信メッセージが表示されます。
このページで、下部のペインでサブスクリプションを選択すると、[Service Bus サブスクリプション] ページが表示されます。 このページで、アクティブなメッセージ数や配信不能メッセージ数を確認できます。 この例では、受信者がまだ受信していないアクティブなメッセージが 10 個あります。
トラブルシューティング
必要なクレームに関する JavaScript コードのパスワードレス バージョンを実行するとエラーが発生する場合は、Azure CLI コマンド az login
を使ってサインインしていること、および適切なロールが Azure ユーザー アカウントに適用されていることを確認します。
リソースをクリーンアップする
Azure portal で Service Bus 名前空間に移動し、Azure portal で [削除] を選択して名前空間とその中のキューを削除します。
次のステップ
次のドキュメントおよびサンプルを参照してください。