方法A:
2つの別々のホスト(つまり、1つはWCFサービス用、もう1つは「ポーリング」サービス用)を作成する場合、すべてを正常に機能させるためのオプションは1つだけです。
Windowsサービスの通信は非常に制限されています(WCFなどのサービスエンドポイントの助けがない場合)。そのため、Windowsサービスで「ポーリング」サービスをホストする場合は、とにかくそれをWCFサービスと結合する必要があります。
その後、1つのWindowsサービスで両方のサービスを一緒にホストし、WCFホストを手動でインスタンス化し、コンストラクターに「ポーリング」サービスを渡すことで実行できます。
protected override void OnStart(string[] args)
{
//...
// This would be you "polling" service that would start a background thread to poll the db.
var notificationHost = new PollingService();
// This is your WCF service which you will be "self hosted".
var serviceHost = new WcfService(notificationHost);
new ServiceHost(serviceHost).Open();
//...
}
2つのサービス間でイベントを介して通信する必要があるため、これは理想からはほど遠いです。さらに、手動インスタンス化を機能させるには、WCFサービスをシングルトンモードで実行する必要があります。
方法B:
WCFサービス内で「ポーリング」サービスをホストする場合、いくつかの問題が発生します。
- 作成される「ポーリング」サービスのインスタンスの数に注意する必要があります。WCFサービスがセッションごとにインスタンス化されるように構成されている場合、「ポーリング」サービスが多すぎて、データベース/サーバーが停止する可能性があります。
- 最初の問題を回避するには、シングルトンWCFサービスを設定する必要がある場合があります。これにより、近い将来、1つのWCFサービスインスタンスでは接続要求の数を処理するのに十分でないスケーリングの問題が発生する可能性があります。
方法C:
方法AとBの欠点を考えると、最善の解決策は2つの独立したWCFサービスをホストすることです。
- これは、サブスクライバー/サブスクライブ解除/公開がある通常のサービスです。
- これは、サブスクライブ/サブスクライブ解除を使用したポーリングシングルトンサービスです。
通常のサービスは、サブスクライバーを受信すると、ポーリングサービスへの新しい接続を開くか、既存の接続を使用して(セッションの構成方法に応じて)、応答を待つという考え方です。ポーリングサービスは、データベースをポーリングし、そのサブスクライバー(つまり、他のWCFホスト)に通知を公開する、長時間実行されるWCFサービスです。
長所:
- ポーリングサービスは1つだけです。
- ソリューションをスケーリングして、IISで通常のサービスをホストし、Windowsサービスでポーリングサービスをホストすることができます。
- 2つのサービス間の通信制限は最小限であり、イベントは必要ありません。
- インターフェースを介して各サービスを相互に依存してテストします。
- サービス間の結合度が低く、凝集度が高い(これが私たちが望んでいることです!)。
短所:
- より多くのサービスは、維持するためのより多くのインターフェースと契約を意味します。
- より複雑。