2

通知/リマインダーを取得するためにすべてのクライアントが接続するWCFサービスがあります(クライアントが実装するCALLBACKインターフェイスを使用)。現在、WCFサービスは自己ホスト型ですが、Windowsサービスでホストする予定です。

WCFサービスには、「パブリッシュ」、「サブスクライブ」、および「サブスクライブ解除」の操作があります。

ある種のバックグラウンドワーカースレッドでSQLサーバーデータベーステーブルを常に[XXX分ごとに]ポーリングし、特定の「リマインダー」行を探す必要があります。それらが見つかると、接続されているすべてのクライアントに通知する必要があります。

これを実現する2つの方法を考えました。

方法A:

バックグラウンドスレッドを開始して実行する別のEXEプロジェクト(コンソールにしたくないので、Windowsサービスはどうあるべきですか?)を用意します。バックグラウンドスレッドは、クライアントの1つとして「リマインダー」サービスに接続します。バックグラウンドスレッドはデータベースをポーリングし、何かが見つかると、「公開」メッセージをWCFサービスに送信します。これにより、WCFサービスはサブスクライブされたすべてのクライアントにリマインダーを送信します。

方法B:

どういうわけかバックグラウンドスレッドをWCFサービスプロジェクト内で実行し、データベースで新しいリマインダー行を検出したら、どういうわけかそれをWCFサービスに情報で「通知」し、WCFサービスはこの情報をすべてのサブスクライブされたクライアントに送信します。

どちらの方法が良いですか?他の提案はありますか?

4

2 に答える 2

6

これが長時間実行されるプロセスである場合は、Windowsサービスが最適なソリューションです。メインのWinServiceスレッドは、DBをポーリングし、結果をある種のサプライヤー/コンシューマースレッドセーフコレクションにキューイングします。

Winサービス内でWCFサービスをホストできます。これにより、キューから結果を消費(削除)し、要求に応じてクライアントに返すことができます(WCFへの呼び出しは独自のスレッドで行われます)。

これはかなり一般的なアーキテクチャであり、実装は難しくありません。

于 2012-06-30T13:38:40.733 に答える
1

方法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サービス内で「ポーリング」サービスをホストする場合、いくつかの問題が発生します。

  1. 作成される「ポーリング」サービスのインスタンスの数に注意する必要があります。WCFサービスがセッションごとにインスタンス化されるように構成されている場合、「ポーリング」サービスが多すぎて、データベース/サーバーが停止する可能性があります。
  2. 最初の問題を回避するには、シングルトンWCFサービスを設定する必要がある場合があります。これにより、近い将来、1つのWCFサービスインスタンスでは接続要求の数を処理するのに十分でないスケーリングの問題が発生する可能性があります。

方法C:

方法AとBの欠点を考えると、最善の解決策は2つの独立したWCFサービスをホストすることです。

  1. これは、サブスクライバー/サブスクライブ解除/公開がある通常のサービスです。
  2. これは、サブスクライブ/サブスクライブ解除を使用したポーリングシングルトンサービスです。

通常のサービスは、サブスクライバーを受信すると、ポーリングサービスへの新しい接続を開くか、既存の接続を使用して(セッションの構成方法に応じて)、応答を待つという考え方です。ポーリングサービスは、データベースをポーリングし、そのサブスクライバー(つまり、他のWCFホスト)に通知を公開する、長時間実行されるWCFサービスです。

長所:

  1. ポーリングサービスは1つだけです。
  2. ソリューションをスケーリングして、IISで通常のサービスをホストし、Windowsサービスでポーリングサービスをホストすることができます。
  3. 2つのサービス間の通信制限は最小限であり、イベントは必要ありません。
  4. インターフェースを介して各サービスを相互に依存してテストします。
  5. サービス間の結合度が低く、凝集度が高い(これが私たちが望んでいることです!)。

短所:

  1. より多くのサービスは、維持するためのより多くのインターフェースと契約を意味します。
  2. より複雑。
于 2013-01-29T02:10:06.943 に答える