2011-12-19 102 views
4

我正在使用WCF,我在我的C#計劃中添加了一個聊天室設施。所以,我需要能夠從服務器向客戶端發送信息的兩個事件 -聊天室功能與WCF,雙工回調與輪詢?

  • 當用戶連接/斷開我更新連接的用戶列表,併發送回所有客戶端顯示在一個TextBlock
  • 當用戶發佈消息,我需要的服務器來發送郵件給所有客戶

所以我要尋找的建議在實施這一點的最好辦法。我打算使用netTcpBinding作爲客戶端的雙工回調,但後來我遇到了一些問題,關於在連接關閉時無法回撥客戶端。我需要使用percall實例來提高可擴展性。我被告知在這個線程,我不應該離開連接打開,因爲它會'大大限制scalibity' - WCF duplex callbacks, how do I send a message to all clients?

但是,我看了一本書編程WCF服務和作者似乎說,這不是一個問題,因爲'在兩次調用之間,客戶端持有一個代理服務器上的引用,該代理服務器沒有實際的對象。這意味着,你可以配置昂貴的資源的服務實例佔用客戶端關閉代理」

  1. 因此,這是正確的,是細保持代理客戶端上的長開過嗎?
  2. 但即使這很好,它會導致另一個問題。如果服務實例在通話之間被破壞,他們如何執行雙工回調來更新客戶端?關於percall實例,編程WCF服務的作者說'因爲一旦方法返回,對象將被丟棄,你不應該分離後臺線程或分派異步調用回實例'
  3. 我會更好的客戶端投票更新服務?我會想象這比雙工回調的效率低得多,客戶最終可能會使用雙工回調的次數高達50次以上。但也許沒有其他辦法?這是可擴展的嗎?我設想幾百個併發用戶。

回答

1

由於我有罪告訴你服務器回調不會擴展,我應該多解釋一下。讓我解決您的問題開始:

  1. 沒有擁有自己的書有問題,我只能假設,筆者要麼指基於http傳輸或僅請求 - 響應,沒有回調。回調需要兩件事之一 - 或者服務器需要維護與客戶端的開放式TCP連接(意味着每個客戶端有服務器上正在使用的資源),或者服務器需要能夠打開連接以偵聽端口在客戶端。既然你使用的是netTcpBinding,你的情況就是前者。 wsDualHttpBinding是後者的一個例子,但是它引入了很多路由和防火牆問題,使得它在互聯網上無法使用(我假設公共互聯網是您的目標環境 - 如果沒有,請告訴我們)。

  2. 您已經直觀地理解了回調需要服務器資源的原因。同樣,wsDualHttpBinding有點不同,因爲在這種情況下,服務器實際上是通過新的連接向客戶端回叫以發送異步回覆。這基本上要求在客戶端打開端口,並穿過任何防火牆,這是普通互聯網用戶所不能期望的。其它更多關於這裏:WSDualHttpBinding for duplex callbacks

  3. 您可以構建這幾種不同的方式,但如果你不希望不斷錘擊更新服務器的客戶端的開銷(和潛在的延遲)這是可以理解的。同樣,在幾百個併發用戶中,您可能仍然處於一個好的服務器可以使用回調處理的範圍內,但是我認爲您希望有一個系統可以在需要時(或在高峯時間)擴展。我會做的是:

    1. 使用回叫代理(我知道,我告訴你不要)......連接創建新的代理,其存儲在一個線程安全的集合,偶爾檢查客戶端活着(如果發現死亡則清除)。

    2. 而不是讓服務器直接從一個客戶端發送消息到另一個客戶端,讓服務器發送消息到一些Message Queue Middleware。有很多這些 - MSMQ是受Windows的歡迎,ActiveMQRabbitMQ是免費開源軟件,並且Tibco EMS在大型企業中很受歡迎(但可能非常昂貴)。你可能想要使用的是一個主題,而不是一個隊列(更多關於隊列與主題here)。

    3. 具有專用於閱讀關閉消息的話題服務器上的線程(或多個線程),並如果該消息被髮送到實時會話服務器上,傳遞這一信息轉達給服務器上的代理。

這裏的建築的草圖:

Queue-backed Chat Architecture

此架構應允許您通過簡單地增加更多的服務器和負載平衡它們之間的新連接會自動向外擴展。消息隊列基礎設施將是唯一的限制因素,我提到的所有這些都將超出您所看到的任何可能的用例。由於您使用的是主題而不是隊列,因此每條消息都會廣播到每個服務器,您可能需要找出一種更好的分發消息的方式,例如使用基於散列的分區。