サービスバスの利用
AppFabricサービスバスの利用方法を、サンプルを元に解説していきます。本稿で説明するサンプルは全体の抜粋となっているので、詳細はサンプルファイルを確認してください。
では、サンプルファイルをダウンロードしてソリューリョンファイルを開きます。下表の3つのプロジェクトが含まれています。
| プロジェクト名 | 説明 |
| OnPremiseService | サービス提供プログラム。AppFabricサービスバスへサービスを登録、提供する。 |
| OnPremiseClient | サービスを利用するクライアントプログアム。 |
| WebRole1 | Windows Azure上からサービスを利用するクライアントプログラム。 |
これらのプロジェクトを示したものが図4です。それぞれ、オンプレミスからの利用を想定した、OnPremiseService/OnPremiseClientプロジェクト、クラウドからの利用を想定したWebRole1プロジェクトとなっています。
コントラクト
サービス作成に先立って、各アプリケーション間で交換するサービスを定義します。AppFabricサービスバスでは、WCFと同じくサービスコントラクトとオペレーションコントラクトを定義します(リスト2)。コントラクトとは、共通のインターフェースを定義するものと考えてください。
// サービスコントラクトの定義
[ServiceContract]
public interface IEchoService
{
// 操作の定義
[OperationContract]
string Echo(string name);
}
// クライアントが利用するチャネル
public interface IEchoChannel : IEchoService, IClientChannel
{
}
サービスとして公開したいインターフェースはServiceContract属性、メソッドにはOperationContranct属性を指定します。このようなプログラミングモデルはWCFとまったく同じです。また、IEchoChannelは、クライアント側からサービスを利用するためにチャネルを定義します。
リスト3は、IEchoServiceインターフェースを実装したEchoServiceクラスで、サービス本体の実装クラスとなります。
class EchoService : IEchoService
{
public string Echo(string message)
{
string reply = string.Format("{0} : {1}", DateTime.Now, message);
Console.WriteLine("返信 : {0}", reply);
return reply;
}
}
上記の例では、Echoメソッドはメッセージを受け取り、それを加工し呼び出し元に返却します。
サービスプログラム
インターフェースとなるコントラクトを定義したところで、サービスを登録、提供する側から見ていきましょう。
リスト4は、サービスを登録するプログラムですが、コード量の少なさが目立ちます。前述したバインディングなどもコード中に表れません。このプログラミング方法についても、WCFと同じく、必要な情報は、アプリケーション構成ファイルで定義して利用するといった手法がとられます。これによって、再コンパイルなしに、構成ファイルの変更のみで設定情報を変更することができるといったメリットがあります。すべてをコードで実装する方法もありますが、本稿では説明しません。
// サービスバスの接続モードを選択
ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.AutoDetect; *1
// URI情報を取得
string schema = ConfigurationManager.AppSettings["schema"];
string serviceNamespace = ConfigurationManager.AppSettings["namespace"];
string servicePath = ConfigurationManager.AppSettings["path"];
// サービス向けURIの生成
Uri address = ServiceBusEnvironment (schema, *2
serviceNamespace,
servicePath);
// サービスのホスト開始
ServiceHost host = new ServiceHost(typeof(EchoService), address); *3
host.Open();
Console.WriteLine("サービス開始 : {0}", address);
Console.WriteLine("[Enter]で終了");
Console.ReadLine();
host.Close();
*1では、サービスバスの接続モードを設定しています。AutoDetect/Tcp/Httpを選択可能です。Tcp/Httpはそれぞれの接続プロトコルを明示的に指定します。AutoDetectは、まずTcpで接続を試行し、失敗したらHttpに切り替えるといった動作をします。利用環境におけるアウトバウンドポートの開放状況が不明な場合は、AutoDetectで問題ありません。
*2は、AppFabricサービスバスのアドレスを生成しています。必要な情報は、アプリケーション構成ファイルから取得しています。このサンプルでは「sb://sb-sample.servicebus.windows.net/sample/」というURIが作成されます。
*3は、最後にServiceHostクラスで、AppFabricサービスバスにサービスを登録します。
次に、アプリケーション構成ファイルを見てみましょう(リスト5)。先ほどのプログラムより多くの行数が記述されており、バインディングの定義も含まれています。
<?xml version="1.0"?>
<configuration>
<appSettings> *1
<add key="schema" value="sb"/>
<add key="namespace" value="sb-sample"/>
<add key="path" value="sample"/>
</appSettings>
...
<system.serviceModel>
<extension>
<!-- サービスバスの構成設定 --> *2
</extention>
<services>
<service name="OnPremiseService.EchoService"> *3
<endpoint contract="OnPremiseService.IEchoService"
binding="netRelayBinding"
bindingConfiguration="EndpointConfig"
behaviorConfiguration ="EndpointBehavior" />
</service>
</services>
<bindings> *4
<netTcpRelayBinding>
<binding name="EndpointConfig">
<security relayClientAuthenticationType="RelayAccessToken" />
</binding>
</netTcpRelayBinding>
</bindings>-->
<behaviors> *5
<endpointBehaviors>
<behavior name="EndpointBehavior">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="owner"
issuerSecret="<<既定のキー>>"/>
</clientCredentials>
</transportClientEndpointBehavior>
<serviceRegistrySettings discoveryMode="Public"/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
*1は、AppFabricサービスバスのスキーマ、サービス名前空間、サービスパスの定義です。netTcpRelayBindingを利用する場合、スキーマは「sb」となります。サービス名前空間には作成したサービス名前空間を指定し、サービスパスはサービスをホストしたいパスを指定します。
*2は、先ほど説明した「サービスバスの構成設定」の通り、サービスバスの構成設定を追加します。
*3のservice要素配下は、サービスの構成をしています。コントラクト、バインディングを指定し、エンドポイントの設定や、ビヘイビアについては他の要素への参照となっています。
*4のbindings要素配下は、バインディングの構成を設定しています。この例では、security要素でクライアント認証が必要な定義をしています。既定はクライアント認証ありのため、この定義自体は無くても構わないのですが、構成例として明示的に記述してあります。
*5のbehavior要素で、エンドポインへのビヘイビアを定義します。transportClientEndpointBehavior要素では、サービス登録に必要な発行者(Issuer Name)とキー(Issuer Secret)を指定しています。これらの値は、管理ポータルのプロパティから取得できます(図5)。また、serviceRegistrySettings要素のdiscoveryMode属性で「Public」を指定しており、これはエンドポイントの公開を指定しています。
ここでサービスプログラムを実行してみましょう。図6のようにサービス開始とともにURLが表示されれば問題なく動作しています。
前述したとおり、Discovery Modeを「Public」に指定しているため、サービス名前空間のURIにブラウザでアクセスすると、「sample」というサービスが登録されていることが確認できます(図7)。これはあくまで、フィードされるかという指定です。非公開だからといってアクセスできないわけではなく、クライアント側がURIを知っており、正しい認証が受けられればサービスは利用可能です。



