ListBasedPublishSubscribe サンプルは、Windows Communication Foundation (WCF) プログラムとして実装されたリスト ベースの Publish-Subscribe パターンを示しています。
注
このサンプルのセットアップ手順とビルド手順は、このトピックの最後にあります。
リスト ベースの Publish-Subscribe デザイン パターンについては、Microsoft Patterns & Practices パブリケーションの 統合パターンに関するページを参照してください。 Publish-Subscribe パターンは、情報トピックを購読している情報を受け取る受信者の集まりに情報を渡します。 リスト ベースのパブリッシュ/サブスクライブでは、サブスクライバーの一覧が保持されます。 共有する情報がある場合は、一覧の各サブスクライバーにコピーが送信されます。 このサンプルでは、動的なリスト ベースのパブリッシュ/サブスクライブ パターンを示します。このパターンでは、クライアントは必要な頻度でサブスクライブまたはサブスクライブ解除できます。
List ベースの Publish-Subscribe サンプルは、クライアント、サービス、およびデータ ソース プログラムで構成されます。 複数のクライアントと複数のデータ ソース プログラムが実行されている場合があります。 クライアントは、サービスのサブスクライブ、通知の受信、およびサブスクライブ解除を行います。 データ ソース プログラムは、現在のすべてのサブスクライバーと共有する情報をサービスに送信します。
このサンプルでは、クライアントとデータ ソースはコンソール プログラム (.exe ファイル) であり、サービスはインターネット インフォメーション サービス (IIS) でホストされているライブラリ (.dll) です。 クライアントとデータ ソースのアクティビティは、デスクトップに表示されます。
サービスは双方向通信を使用します。
ISampleContract
サービス コントラクトは、ISampleClientCallback
コールバック コントラクトとペアになっています。 このサービスでは、サブスクライブおよびサブスクライブ解除のサービス操作が実装されます。この操作は、クライアントがサブスクライバーの一覧に参加または脱退するために使用します。 サービスは、 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 を呼び出してサービスに参加すると、イベント ハンドラーが提供されます。 クライアントが退出すると、イベント ハンドラーの登録が解除されます。 データ ソースがサービスを呼び出して価格の変更を報告すると、サービスがイベントをトリガーします。 これにより、サービスの各インスタンスが呼び出され、サブスクライブしているクライアントごとに 1 つずつ呼び出され、イベント ハンドラーが実行されます。 各イベント ハンドラーは、コールバック関数を通じてクライアントに情報を渡します。
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 サンプル のOne-Time セットアップ手順を実行していることを確認します。
ソリューションの C# または Visual Basic .NET エディションをビルドするには、「Windows Communication Foundation サンプルのビルド」の手順に従います。
同じコンピューターでサンプルを実行するには
次のアドレスを入力して、ブラウザーを使用してサービスにアクセスできることをテストします:
http://localhost/servicemodelsamples/service.svc
。 応答として確認ページが表示されます。言語固有のフォルダーの下から、\client\bin\ から Client.exe を実行します。 クライアント アクティビティがクライアント コンソール ウィンドウに表示されます。 複数のクライアントを起動します。
言語固有のフォルダーの下から、\datasource\bin\ から Datasource.exe を実行します。 データ ソース アクティビティがコンソール ウィンドウに表示されます。 データ ソースがサービスに情報を送信したら、各クライアントに渡す必要があります。
クライアント、データ ソース、およびサービス プログラムが通信できない場合は、「 WCF サンプルのトラブルシューティングのヒント」を参照してください。
マシン間でサンプルを実行するには
サービス マシンを設定します。
サービス マシンで、ServiceModelSamples という名前の仮想ディレクトリを作成します。 Windows Communication Foundation サンプルのOne-Time セットアップ 手順から Setupvroot.bat バッチ ファイルを使用して、ディスク ディレクトリと仮想ディレクトリを作成できます。
サービス プログラム ファイル %SystemDrive%\Inetpub\wwwroot\servicemodelsamples からサービス マシン上の ServiceModelSamples 仮想ディレクトリにコピーします。 必ず \bin ディレクトリにファイルを含めます。
ブラウザーを使用してクライアント コンピューターからサービスにアクセスできることをテストします。
クライアント マシンを設定します。
言語固有のフォルダーの下にある \client\bin\ フォルダーからクライアント コンピューターにクライアント プログラム ファイルをコピーします。
各クライアント構成ファイルで、サービスの新しいアドレスと一致するようにエンドポイント定義のアドレス値を変更します。 "localhost" への参照を、アドレス内の完全修飾ドメイン名に置き換えます。
データ ソース マシンを設定します。
言語固有のフォルダーの下にある \datasource\bin\ フォルダーからデータ ソース コンピューターにデータ ソース プログラム ファイルをコピーします。
データ ソース構成ファイルで、サービスの新しいアドレスと一致するようにエンドポイント定義のアドレス値を変更します。 "localhost" への参照を、アドレス内の完全修飾ドメイン名に置き換えます。
クライアント コンピューターで、コマンド プロンプトから Client.exe を起動します。
データ ソース コンピューターで、コマンド プロンプトから Datasource.exe を起動します。