2010-12-07 9 views
11

私は現在、WCFおよびWCF Data Services経由でインターネット経由でデータベースと通信するc#.NETデスクトップアプリケーションを開発中です。アプリケーションには、ある間隔でリフレッシュする必要のある箇所が多数存在します。最も簡単な解決策は、これらの領域をタイマーに置き、データベースを再クエリーすることです。しかし、何千ものクライアントがサービス層に接続してデータベースを使用するため、これらの操作はサーバーにとって非常に高価になります。頻繁なデータベースポーリングを管理するための良いC#.NETソリューション

私が検討したのは、クライアントによってポーリングされたRSSフィードを作成し、この特定の領域をいつ更新する必要があるかをクライアントに知らせることです。 RSSフィードは、データベースをポーリングして変更を行うサービスによって管理されるか、またはクライアントによって行われたWCF要求によってキューに入れられたアイテムのリストを通じて反復されます。

また、クライアントからサーバーへの直接的かつ連続的な接続を作成することも考えましたが、どのようなアウトバウンドファイアウォールポートがクライアントから開かれるのかよくわかりません。おそらくポート80/443にしかカウントできません。

私の質問は、この問題を解決するために人々が成功したソリューションは何ですか?人々はRSSをやりましたか? Microsoft Syncサービス?クライアントとサーバー間の双方向通信は、WCF経由でいくつかの保存ポートを介してですか?

アイデアをいただければ幸いです。

答えて

8

私はあなたが2つのアプローチの組み合わせに行きたいと思うかもしれないと思います。まず、クライアントからサーバーへのlong pollingを使用して、クライアントが関心がある変更が発生するとすぐにサーバーに通知することができます。

上記の提案をASPで非常にうまく処理する新技術。 NETはSignalRです。これは、長いポーリングの詳細の大部分を扱います(できるだけWebSocketを使用するため)、心配する必要はありません。

第2に、この質問のタグに基づいて、SQL Serverを使用しているようです。変更が発生したときにDBがサービスに通知するように、関心のあるテーブルでデータベース通知を使用できます。これにより、サービスは長いポーリング接続による変更についてクライアントに通知するようトリガーされます。これはSqlDependencyクラスを使用して行うことができます。

他の方法もありますが、通知を受けてからすべてのクライアントに配信するサービスが1つしかないため、これはおそらく規模が大きくなるでしょう。

+0

+1ですが、長いポーリングを使用する数千のクライアントが心配です。いくつかの環境最適化は、おそらく開いている接続に必要です。私はWCFでこれをやったことがないので、難しさ/ポジティブについてはコメントできません。 – marr75

+0

+1 WCFを使用しているC#の長いポーリング実装について知っていますか?私はそれをgoogledし、良い例を思い付いていない。 – BernicusMaximus

+0

申し訳ありませんが、私はしません。私はSilverlightのWCFにDuplexチャンネルがあることを知っていますが、私が読んだところでは定期的にポーリングし、長いポーリングはしません(http://msdn.microsoft.com/en-us/library/cc645028(VS.95) .aspx) –

0

高価な操作がデータベースをプールするサーバーである場合は、何らかのキャッシュを実装する必要があります。これは、ASP.NETのキャッシュとしての基本的なものでも、memcachedを使ったものとしての高度なものでもあります。

高価な操作がクライアントをサーバーにプールしている場合は、PubSubHubbubでAtomまたはRSSフィードを使用して、サーバーへの要求数を最小限に抑えることができます。それは負荷を処理するいくつかの無料のPubSubHubbubパブリッシャーがいるので安くなるでしょう。

0

あなたはService Brokerに見ることができる、あなたはこのようなWCF接続でコールバックインタフェースを定義することができますが、更新

5

をポーリングする必要はありません。その方法:

[ServiceContract(CallbackContract = typeof(IFooClient))] 

クライアントを開始として、接続はファイアウォールを介して動作するはずです。サーバは変更を登録するメソッドを使用して、

IFooClient client = OperationContext.Current.GetCallbackChannel<IFooClient>(); 

でコールバックインターフェイスを取得し、データ変更に登録されているすべてのクライアントをコールバックすることができます。

+0

私はこのアプローチも好きです。私はそれをさらに調査します。 – BernicusMaximus

0

RSSがWebサービスのキャッシュ情報をデータベースよりも簡単にする理由はわかりません。

2つのオプションを比較するには、レポート内のオブジェクトを最後に(または最後に更新したときなど)誰が編集したのかを知っておく必要があるとしましょう。 RSSフィードでは、フィードをリクエストして取得し、解析し、関連する値に基づいてアクションを実行する必要があります。データベースコールをメモしてキャッシュするWebサービスコールでは、サービスを呼び出してその結果を処理するだけです。私はRSSがより良くなるのを見ることができる唯一の時間は、あなたがコントロールしていない、またはネットクライアントではない複数のクライアントをサポートしている場合と2)同時にポーリングされた値の多くに基づいて行動を取っている場合です。

関連する問題