デザイン パターン:リストに基づく公開/定期受信
ListBasedPublishSubscribe サンプルでは、Windows Communication Foundation (WCF) プログラムとして実装されているリストベースのパブリッシュ/サブスクライブ パターンを示します。
Note
このサンプルのセットアップ手順とビルド手順については、このトピックの最後を参照してください。
リストベースのパブリッシュ/サブスクライブ デザイン パターンについては、Microsoft Patterns & Practices の出版物である『統合パターン』で説明されています。 公開/定期受信パターンは、情報トピックを定期受信する受信者のコレクションに情報を渡します。 リストに基づく公開/定期受信では、サブスクライバのリストが保持されます。 共有情報が存在する場合は、コピーがリスト上の各サブスクライバに送信されます。 このサンプルでは、動的なリストに基づく公開/定期受信パターンを示します。これにより、クライアントは必要に応じて何度でも定期受信または定期受信の解除ができます。
リストに基づく公開/定期受信のサンプルは、クライアント、サービス、およびデータ ソース プログラムで構成されています。 クライアントとデータ ソース プログラムは、複数を実行できます。 クライアントはサービスを定期受信し、通知を受信して、定期受信を解除します。 データ ソース プログラムはサービスに情報を送信し、現在のすべてのサブスクライバでその情報が共有されるようにします。
このサンプルでは、クライアントとデータ ソースはコンソール プログラム (.exe ファイル) で、サービスはインターネット インフォメーション サービス (IIS) でホストされるライブラリ (.dll) です。 クライアントとデータ ソースのアクティビティは、デスクトップに表示されます。
サービスは、双方向通信を使用します。 ISampleContract
サービス コントラクトは ISampleClientCallback
コールバック コントラクトと対になっています。 サービスは Subscribe および Unsubscribe サービス操作を実装します。クライアントはこれらのサービス操作を使用してサブスクライバのリストに参加またはリストへの参加を解除します。 サービスは、さらに PublishPriceChange
サービス操作も実装します。データ ソース プログラムはこれを呼び出して、新しい情報をサービスに提供します。 クライアント プログラムは PriceChange
サービス操作を実装します。サービスはこれを呼び出して、すべてのサブスクライバに価格の変更を通知します。
// Create a service contract and define the service operations.
// NOTE: The service operations must be declared explicitly.
[ServiceContract(SessionMode=SessionMode.Required,
CallbackContract=typeof(ISampleClientContract))]
public interface ISampleContract
{
[OperationContract(IsOneWay = false, IsInitiating=true)]
void Subscribe();
[OperationContract(IsOneWay = false, IsTerminating=true)]
void Unsubscribe();
[OperationContract(IsOneWay = true)]
void PublishPriceChange(string item, double price,
double change);
}
public interface ISampleClientContract
{
[OperationContract(IsOneWay = true)]
void PriceChange(string item, double price, double change);
}
サービスは、すべてのサブスクライバに新しい情報を通知する機構として、.NET Framework イベントを使用します。 クライアントが Subscribe を呼び出してサービスに参加すると、イベント ハンドラが提供されます。 クライアントがサービスへの参加を解除すると、イベントからイベント ハンドラの定期受信が解除されます。 データ ソースが価格の変更を報告するサービスを呼び出すと、サービスはイベントを発生させます。 これにより、サービスの各インスタンスが呼び出されます。このサービスは定期受信した各クライアントのサービスで、この呼び出しによって各インスタンスのイベント ハンドラが実行されます。 各イベント ハンドラは、コールバック関数を使用してクライアントに情報を渡します。
public class PriceChangeEventArgs : EventArgs
{
public string Item;
public double Price;
public double Change;
}
// The Service implementation implements your service contract.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class SampleService : ISampleContract
{
public static event PriceChangeEventHandler PriceChangeEvent;
public delegate void PriceChangeEventHandler(object sender, PriceChangeEventArgs e);
ISampleClientContract callback = null;
PriceChangeEventHandler priceChangeHandler = null;
//Clients call this service operation to subscribe.
//A price change event handler is registered for this client instance.
public void Subscribe()
{
callback = OperationContext.Current.GetCallbackChannel<ISampleClientContract>();
priceChangeHandler = new PriceChangeEventHandler(PriceChangeHandler);
PriceChangeEvent += priceChangeHandler;
}
//Clients call this service operation to unsubscribe.
//The previous price change event handler is unregistered.
public void Unsubscribe()
{
PriceChangeEvent -= priceChangeHandler;
}
//Information source clients call this service operation to report a price change.
//A price change event is raised. The price change event handlers for each subscriber will execute.
public void PublishPriceChange(string item, double price, double change)
{
PriceChangeEventArgs e = new PriceChangeEventArgs();
e.Item = item;
e.Price = price;
e.Change = change;
PriceChangeEvent(this, e);
}
//This event handler runs when a PriceChange event is raised.
//The client's PriceChange service operation is invoked to provide notification about the price change.
public void PriceChangeHandler(object sender, PriceChangeEventArgs e)
{
callback.PriceChange(e.Item, e.Price, e.Change);
}
}
このサンプルを実行すると、複数のクライアントが起動されます。 クライアントはサービスを定期受信します。 次にデータ ソース プログラムが実行され、サービスに情報が送信されます。 サービスは、すべてのサブスクライバに情報を渡します。 各クライアント コンソールでアクティビティを表示し、情報が受信されたことを確認できます。 クライアントをシャットダウンするには、クライアント ウィンドウで Enter キーを押します。
サンプルをセットアップしてビルドするには
Windows Communication Foundation サンプルの 1 回限りのセットアップの手順を実行したことを確認します。
ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「 Building the Windows Communication Foundation Samples」の手順に従います。
サンプルを同じコンピューターで実行するには
次のアドレスを入力して、ブラウザーを使用してサービスにアクセスできることをテストします:
http://localhost/servicemodelsamples/service.svc
。 これに応答して、確認ページが表示されます。言語固有のフォルダーの下の \client\bin\ にある Client.exe を実行します。 クライアント アクティビティがクライアント コンソール ウィンドウに表示されます。 複数のクライアントを起動します。
言語固有のフォルダの下の \datasource\bin\ にある Datasource.exe を実行します。 データ ソース アクティビティがコンソール ウィンドウに表示されます。 データ ソースがサービスに情報を送信すると、その情報は各クライアントに渡されます。
クライアント、データ ソース、サービス プログラムの間で通信できない場合は、WCF サンプルのトラブルシューティングのヒントに関するページをご覧ください。
サンプルを複数コンピューターで実行するには
サービス コンピュータを設定します。
サービス コンピューターで、ServiceModelSamples という仮想ディレクトリを作成します。 「Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」に含まれているバッチ ファイル Setupvroot.bat を使用して、ディスク ディレクトリと仮想ディレクトリを作成できます。
サービス プログラム ファイルを %SystemDrive%\Inetpub\wwwroot\servicemodelsamples からサービス コンピューターの ServiceModelSamples 仮想ディレクトリにコピーします。 \bin ディレクトリのファイルが含まれていることを確認してください。
ブラウザーを使用して、サービスにクライアント コンピューターからアクセスできるかどうかをテストします。
クライアント コンピュータを設定します。
クライアント プログラム ファイルを、言語固有のフォルダにある \client\bin\ フォルダーからクライアント コンピュータにコピーします。
各クライアントの構成ファイルで、エンドポイント定義のアドレス値をサービスの新しいアドレスに合わせて変更します。 アドレスの "localhost" への参照をすべて完全修飾ドメイン名に置き換えます。
データ ソース コンピュータを設定します。
データ ソース プログラム ファイルを、言語固有のフォルダーにある \datasource\bin\ フォルダーからデータ ソース コンピュータにコピーします。
データ ソースの構成ファイルで、エンドポイント定義のアドレス値をサービスの新しいアドレスに合わせて変更します。 アドレスの "localhost" への参照をすべて完全修飾ドメイン名に置き換えます。
クライアント コンピュータで、コマンド プロンプトから Client.exe を起動します。
データ ソース コンピューターで、コマンド プロンプトから Datasource.exe を起動します。