Azure Service Bus をコンソールアプリから使うメモ


Microsoft Azure Service Bus

Azureにはクラウドとオンプレミスのシステムを連携させるためにAzure Service Busがあります。これはメッセージ通信を使用して複数のシステムを連携させる事が出来ます。
最もも利用されるシーンとしては、クラウド上に構築したシステムからオンプレミスのサービスを呼び出すものですが、クラウド上のアプリケーションに限らず、オンプレミスとオンプレミスのアプリケーションの間でも使用することが出来ます。
サービスバスが登場した当時はAppFabric Service Busといわれていたみたいですが、現在ではAppFabricの名前は廃止されたのでそのままService Busと呼ぶみたいです。

AzureのCloudServiceとIaaS上のVM間の連携がゴールではありますが、とりあえずコンソールアプリケーションを2つ作成して、連携出来ることを確認します。

BasicとStandaard

サービスバスにはBasicとStandardの二つのエディションがありますが、連携させる二つのサービス(アプリケーション)間でシンプルな通知を行わせる場合はBasicでまかなうことが出来そうです。
Standardを利用すると、サービス間でのダイレクトな通信(リレー)やトランザクションの実施、独自のフィルタリングの実装(トピック)などより高度な設定を行うことが可能となります。
料金体系はMessageing(メッセージング)についてはBasicは完全従量制、Standardについては基本料金として1,020円/Month、かつ12.5M以上のメッセージングについては従量課金となる模様です。
Brokered connectionsについてはbasicは100、Standardは1000接続までは基本料金に含まれる模様ですが、Brokered connectionsがよく分からず。。。同時接続されるデバイスの数かな??
Relay(リレー)はエンドポイントを開いている時間による従量課金とメッセージ量の従量課金の加算となっています。

サービスバスの作成

コンソールアプリケーションを2つ作成し、サービスバスのメッセージング機能を使用して連携させます。最初にAzure上にサービスバスを作成します。

  1. Azureの管理ポータルにログインし左側のメニューリストから[Service Bus]を選択します。
  2. 下にある[作成]を選択し、サービスバスの名称(hogepiyo)とリージョン(西日本)、種類(メッセージング)、メッセージングプラン(Basic)を設定し実行します。

  3. 画面が遷移しサービスバスが作成されます。

  4. 続いてアクセスするための接続情報をコピーするため、画面下部の[接続情報]を選択します。

  5. 名前とキーが表示されるので手元にコピーします。

送信側アプリケーション

VisualStudioを起動し新規のプロジェクトを作成、Visual C#を選択しコンソールアプリケーションを選択します。
ソリューションエクスプローラーから[参照設定]を右クリックし、[Nugetパッケージの管理]を起動します。[Service Bus]で検索を行い[Microsoft Azure Service Bus]を依存する[Windows Azure Configuration Manager]と共にインストールします。

サービスバスのパッケージをインストールすると、自動的にApp.Configにサービスバスへアクセスするための設定情報がひな形として記述されます。コードを書く前に変更を行います。ReplaceYourNameとReplaceYourKeyを置き換えますが、サービスバスの作成の最後で得た文字列をvalueの後ろにそのままコピー&ペーストすれば置き換えられます。

App.config
  <appSettings>
    <!-- Service Bus specific app setings for messaging connections -->
    <add key="Microsoft.ServiceBus.ConnectionString" value="Endpoint=sb://ReplaceYourName.servicebus.windows.net;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=ReplaceYourKey" />
  </appSettings>

コードを下記のように変更します。

sender.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

//Azureにアクセスするために下記のモジュールを読み込む
using Microsoft.WindowsAzure;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;

namespace AzureSBSender
{
    class Program
    {
        static void Main(string[] args)
        {
            //キューの名称を設定
            string queueName = "hogepiyoQueue";

            //キューの最大サイズ(1GB)とタイムアウト時間(1時間)を設定
            QueueDescription qd = new QueueDescription(queueName);
            qd.MaxSizeInMegabytes = 1024;
            qd.DefaultMessageTimeToLive = new TimeSpan(1, 0, 0);

            //App.Configからサービスバスへの接続情報を読み込む
            string connectionString =
                CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            //サービスバスを管理するためのNamespaceManagerを作成する
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);

            //キューがなければ作成する
            if (!namespaceManager.QueueExists(queueName))
            {
                namespaceManager.CreateQueue(qd);
            }

            //キューのクライアントを取得
            QueueClient client = QueueClient.CreateFromConnectionString(connectionString, queueName);
            //送信するメッセージの本体を生成
            BrokeredMessage message = new BrokeredMessage("Test Message.");
            //メッセージを送信
            client.Send(message);
            Console.WriteLine("Message(s) sent.");
            Console.WriteLine("Done, press a key contirue.");
            Console.ReadKey();
        }
    }
}

受信側アプリケーション

受信側のアプリケーションを作成しますが、基本的には送信側アプリケーションと同じ要領でNugetによるService Busの読み込みと、App.configの書き換えを行います。

reciever.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;


namespace AzureSBReciever
{
    class Program
    {
        static void Main(string[] args)
        {
            string queueName = "hogepiyoQueue";

            QueueDescription qd = new QueueDescription(queueName);
            qd.MaxSizeInMegabytes = 1024;
            qd.DefaultMessageTimeToLive = new TimeSpan(1, 0, 0);

            string connectionString =
                CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString");
            var namespaceManager = NamespaceManager.CreateFromConnectionString(connectionString);

            if (!namespaceManager.QueueExists(queueName))
            {
                namespaceManager.CreateQueue(qd);
            }

            QueueClient client = QueueClient.CreateFromConnectionString(connectionString, queueName);

            //ループでメッセージを待ち受ける
            while (true)
            {
                //メッセージを受信
                BrokeredMessage retrievedMessage = client.Receive();
                if (retrievedMessage != null)
                {
                    try
                    {
                        //メッセージのIDと本体を表示
                        Console.WriteLine("Message(s) Retrieved: " + retrievedMessage.MessageId +
                            ":" + retrievedMessage.GetBody<string>());
                        //受信処理を終了
                        retrievedMessage.Complete();
                    }

                    catch(Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                        //メッセージのロックを破棄する
                        retrievedMessage.Abandon();
                    }
                }
            }
        }
    }
}

結果

送信側です。

受信側はメッセージIDとメッセージの本文が取得出来ていることが分かります。

オンプレミスとオンプレミスのアプリケーション同士ですが、Azureのサービスバスを使うと連携を行うことが出来ます。

終了。