簡體   English   中英

WCF的聊天室功能,雙工回調與輪詢?

[英]Chatroom functionality with WCF, duplex callbacks vs polling?

我正在使用WCF ,我在我的C#程序中放了一個聊天室設施。 所以我需要能夠從服務器向客戶端發送兩個事件的信息 -

  • 當用戶連接/斷開連接時,我更新已連接用戶的列表並將其發送回所有客戶端以在TextBlock中顯示
  • 當用戶發布消息時,我需要服務器將該消息發送給所有客戶端

所以我正在尋找有關實施此方法的最佳方法的建議。 我打算使用netTcpBinding對客戶端進行雙工回調,但后來遇到一些問題,如果連接關閉則無法回調客戶端。 我需要使用percall實例來提高可擴展性。 在這個帖子中我被告知我不應該打開連接,因為它會“顯着限制scalibity” - WCF雙工回調,如何向所有客戶端發送消息?

但是,我查看了編程WCF服務一書,作者似乎說這不是問題,因為'在兩次調用之間,客戶端持有對代理的引用,該代理在結尾處沒有實際對象。線。 這意味着您可以在客戶端關閉代理之前很久就處理服務實例占用的昂貴資源

  1. 那么哪個是正確的,保持代理在客戶端打開是否正常?
  2. 但即使這很好,也會導致另一個問題。 如果在呼叫之間銷毀服務實例,他們如何進行雙工回調以更新客戶端? 關於percall實例,編程WCF服務的作者說'因為一旦方法返回就會丟棄該對象,你不應該脫離后台線程或將異步調用發送回實例'
  3. 讓客戶輪詢服務以獲取更新會更好嗎? 我可以想象這比雙工回調效率低得多,客戶端最終可能會使用雙工回調頻繁地輪詢服務50倍。 但也許別無他法? 這可以擴展嗎? 我設想了幾百個並發用戶。

因為我告訴你服務器回調不會擴展,我應該解釋一下。 首先讓我談談你的問題:

  1. 如果不擁有相關書籍,我只能假設作者要么僅提到基於http的傳輸或請求響應,而沒有回調。 回調需要兩件事之一 - 服務器需要維護與客戶端的開放TCP連接(意味着服務器上有每個客戶端使用的資源),或者服務器需要能夠打開連接到監聽客戶端上的端口。 由於您使用的是netTcpBinding,因此您的情況將是前者。 wsDualHttpBinding是后者的一個例子,但是它引入了許多路由和防火牆問題,使得它在互聯網上無法工作(我假設公共互聯網是你的目標環境 - 如果沒有,請告訴我們)。

  2. 您已經直觀地弄清楚了回調需要服務器資源的原因。 同樣,wsDualHttpBinding有點不同,因為在這種情況下,服務器實際上是通過新連接回調客戶端以發送異步回復。 這基本上要求在客戶端打開端口並穿過任何防火牆,這是普通互聯網用戶所不能想到的。 這里有更多: WSDualHttpBinding用於雙工回調

  3. 您可以通過幾種不同的方式對此進行構建,但如果您不希望客戶端的開銷(以及延遲的可能性)不斷地敲擊服務器以進行更新,那么這是可以理解的。 同樣,在幾百個並發用戶中,您可能仍然處於一個好的服務器可以使用回調處理的范圍內,但我認為您希望系統能夠在需要時(或在高峰時間)擴展到超出該范圍的系統。 我要做的是:

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

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

    3. 在服務器上有一個專門用於讀取主題消息的線程(或多個線程), 如果該消息發送到該服務器上的實時會話 ,則將該消息傳遞給服務器上的代理。

這是架構的草圖:

隊列支持的聊天架構

此體系結構應允許您通過簡單地添加更多服務器來自動擴展,並在它們之間負載平衡新連接。 消息排隊基礎設施將是唯一的限制因素,我提到的所有內容都將超出您所見過的任何可能的用例。 因為您將使用主題而不是隊列,所以每條消息都將被廣播到每個服務器 - 您可能需要找出一種更好的方式來分發消息,例如使用基於散列的分區。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM