2012-06-30 37 views
2

我有一個WCF服務,所有客戶端連接到爲了得到通知\提醒(使用他們實現的CALLBACK接口)。目前WCF服務是自託管的,但計劃是將其託管在Windows服務中。如何使用後臺工作線程創建WCF服務?

WCF服務有'發佈','訂閱'和'取消訂閱'操作。

我需要有一個後臺工作線程某種類型不斷查詢SQL服務器數據庫表[每XXX分鐘],並尋找某些'提醒'行。一旦發現它們 - 它應該通知所有連接的客戶端。

我想到了實現這一點的兩種方法。

方法:

有一個單獨的EXE項目(不希望它是一個控制檯,還等什麼它應該是 - 一個Windows服務?),將啓動和運行一個後臺線程。後臺線程將作爲其客戶之一連接到「提醒」服務。後臺線程將輪詢數據庫,一旦發現問題 - 它會向WCF服務發送「發佈」消息,這將使WCF服務將提醒發送給所有訂閱的客戶端。

方法B:

不知怎的讓後臺線程運行 WCF服務項目,當它檢測到數據庫中的一個新的提醒行,不知何故使得「信號」的WCF服務與信息,然後WCF服務將把這個信息發送給所有訂閱的客戶端。

哪種方法更好?還有其他建議嗎?

回答

1

方法A:

如果你要創建兩個單獨的主機(即一個WCF服務,一個用於「輪詢」服務),那麼你真的只有一個選項,以使所有的工作很好。

Windows服務通信非常有限(沒有服務端點的幫助,例如WCF)。因此,如果您要在Windows服務中託管您的「輪詢」服務,則無論如何您必須將其與WCF服務連接起來。

然後在一個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(); 
    //... 
} 

這是很不理想,因爲你需要通過事件的兩個服務之間的溝通,再加上你的WCF服務必須手動實例化上下工夫單模式下運行......所以這給你留下...

方法B:

如果你要承載您的WCF服務裏面的「查詢」服務,你會碰到一些問題。

  1. 您需要了解創建的「輪詢」服務實例的數量。如果您的WCF服務已配置爲每個會話都實例化,則最終可能會有太多「輪詢」服務,最終可能會導致您的數據庫/服務器死機。
  2. 爲了避免第一個問題,您可能需要設置一個單例WCF服務,這可能會在不久的將來導致一個擴展問題,即一個WCF服務實例不足以處理連接請求的數量。

方法C:

鑑於方法A和B的弊端,最好的解決辦法是舉辦兩個獨立的WCF服務。

  1. 這是您的訂閱/取消訂閱/發佈的常規服務。
  2. 這是您的訂閱/取消訂閱的輪詢單身服務。

這個想法是,您的常規服務在收到訂閱者後會打開一個到您的輪詢服務的新連接或使用現有的連接(取決於您如何配置會話)並等待回覆。您的輪詢服務是一個長時間運行的WCF服務,用於輪詢您的數據庫並將通知發佈給其訂閱者(即另一個WCF主機)。

優點:

  1. 你放心,會出現只有一個輪詢服務。
  2. 您可以擴展您的解決方案以託管IIS中的常規服務和Windows服務中的輪詢服務。
  3. 兩種服務之間的通信限制最小,不需要事件。
  4. 通過它們的接口相互依賴地測試每個服務。
  5. 服務之間低耦合和高內聚(這是我們想要的!)。

缺點:

  1. 更多的服務意味着更多的接口和契約來維持。
  2. 更復雜。
6

如果這是一個長期運行的過程,Windows服務是一個完美的解決方案。 您的主要Win服務線程將輪詢數據庫,將結果排隊等待某種供應商/消費者線程安全收集。

您可以在win服務中託管一個WCF服務,然後它可以從隊列中消耗(除去)任何結果並根據請求將它們傳回給客戶端(調用WCF將自行進入)

這是一個很常見的架構,並不難實現。

+0

可以使用高性能緩存系統(如Couchbase或AppFabric)來存儲排隊數據。通過這種方式,數據不會變化。 –

+0

如何使WCF服務「消耗」隊列中的結果? 這將建議WCF服務本身應該有一些工作線程輪詢隊列...你有我的任何示例\示例代碼? (你說這是一個普通的架構) –

+0

@Erix - 你有答案嗎? –