デザイン パターン : リストに基づく公開/購読

このサンプルでは、Windows Communication Foundation (WCF) プログラムとして実装された、リストに基づく公開/購読パターンを示します。

ms752254.note(ja-jp,VS.100).gif注 :
このサンプルのセットアップ手順とビルド手順については、このトピックの最後を参照してください。

リストに基づく公開/購読のデザイン パターンは、「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 deregistered.

        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 キーを押します。

サンプルをセットアップしてビルドするには

  1. Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」が実行済みであることを確認します。

  2. ソリューションの C# 版または Visual Basic .NET 版をビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。

サンプルを同じコンピュータで実行するには

  1. ブラウザにアドレス「https://localhost/servicemodelsamples/service.svc」を入力して、サービスにアクセスできるかどうかをテストします。これに対して確認ページが表示されます。

  2. 言語固有のフォルダの下の \client\bin\ にある Client.exe を実行します。クライアント アクティビティがクライアント コンソール ウィンドウに表示されます。複数のクライアントを起動します。

  3. 言語固有のフォルダの下の \datasource\bin\ にある Datasource.exe を実行します。データ ソース アクティビティがコンソール ウィンドウに表示されます。データ ソースがサービスに情報を送信すると、その情報は各クライアントに渡されます。

  4. クライアント、データ ソース、およびサービス プログラムが通信できない場合は、「Troubleshooting Tips」を参照してください。

サンプルを別のコンピュータで実行するには

  1. サービス コンピュータを設定します。

    1. サービス コンピュータで、ServiceModelSamples という仮想ディレクトリを作成します。「Windows Communication Foundation サンプルの 1 回限りのセットアップの手順」でバッチ ファイル Setupvroot.bat ファイルを使用すると、ディスク ディレクトリと仮想ディレクトリを作成できます。

    2. サービス プログラム ファイルを %SystemDrive%\Inetpub\wwwroot\servicemodelsamples からサービス コンピュータの ServiceModelSamples 仮想ディレクトリにコピーします。\bin ディレクトリのファイルが含まれていることを確認してください。

    3. ブラウザを使用して、サービスにクライアント コンピュータからアクセスできるかどうかをテストします。

  2. クライアント コンピュータを設定します。

    1. クライアント プログラム ファイルを、言語固有のフォルダにある \client\bin\ フォルダからクライアント コンピュータにコピーします。

    2. 各クライアントの構成ファイルで、エンドポイント定義のアドレス値をサービスの新しいアドレスに合わせて変更します。アドレスの "localhost" への参照をすべて完全修飾ドメイン名に置き換えます。

  3. データ ソース コンピュータを設定します。

    1. データ ソース プログラム ファイルを、言語固有のフォルダにある \datasource\bin\ フォルダからデータ ソース コンピュータにコピーします。

    2. データ ソースの構成ファイルで、エンドポイント定義のアドレス値をサービスの新しいアドレスに合わせて変更します。アドレスの "localhost" への参照をすべて完全修飾ドメイン名に置き換えます。

  4. クライアント コンピュータで、コマンド プロンプトから Client.exe を起動します。

  5. データ ソース コンピューターで、コマンド プロンプトから Datasource.exe を起動します。

ms752254.Important(ja-jp,VS.100).gif 注 :
サンプルは、既にコンピューターにインストールされている場合があります。続行する前に、次の (既定の) ディレクトリを確認してください。

<InstallDrive>:\WF_WCF_Samples

このディレクトリが存在しない場合は、「.NET Framework 4 向けの Windows Communication Foundation (WCF) および Windows Workflow Foundation (WF) のサンプル」にアクセスして、Windows Communication Foundation (WCF) および WF のサンプルをすべてダウンロードしてください。このサンプルは、次のディレクトリに格納されます。

<InstallDrive>:\WF_WCF_Samples\WCF\Scenario\DesignPatterns/ListBasedPublishSubscribe