2014-11-04 86 views
13

我有一個Windows服務託管一個高級的WCF服務,通過TCP(netTCP)與protobuf.net進行通信,有時還有證書。KeepAlive與WCF和TCP?

receiveTimeout設置爲無限以永不放棄由於不活動而導致的連接。但從我所瞭解的連接可能會被丟棄,所以我創建了一個簡單的雙向Keepalive服務方法,客戶端每9分鐘調用一次以保持連接的活躍。連接永不中斷是非常重要的。

這是正確的方法嗎?或者我可以簡單地刪除我的保持生活,因爲receiveTimout設置爲無限?

編輯:爲WCF服務當前的app.config:http://1drv.ms/1uEVKIt

+0

如果您打算保持連接處於打開狀態,您必須定期發送ping數據包,否則有狀態路由器可能會由於不活動而丟棄連接。 – 2014-11-04 11:56:13

+0

好的,我怎麼知道這個ping必須被髮送的頻率? – Banshee 2014-11-04 12:09:04

+0

連接由於瞬時錯誤而下降時會發生什麼?你無法阻止這一點。 – usr 2014-11-04 13:02:41

回答

30

號這被許多人誤解了,可惜有很多誤傳那裏。

首先,「無限」是一種半有效值。有兩個特殊的配置序列化器可將「無限」轉換爲TimeSpan.MaxValueint.MaxValue(因此它們不是真正的「無限」),但並非WCF中的所有內容似乎都能識別這一點。所以最好是用時間值明確指定你的超時時間。

其次,您的服務中不需要「keepalive」方法,因爲WCF提供了所謂的「可靠會話」。如果添加<reliableSession enabled="true" />,則WCF將通過「基礎結構消息」提供它自己的保持活動機制。

通過擁有自己的「keepalive」機制,您的服務負載實際上翻了一番,而且實際上可以創建比解決問題更多的問題。

第三,使用可靠的會話時,可以使用inactivityTimeout設置reliableSession。這有兩件事。首先,它控制發送基礎設施(Keepalive)消息的頻率。它們以超時值的一半發送,所以如果將它設置爲18分鐘,那麼它們將每9分鐘發送一次。其次,如果在不活動超時時間內沒有收到基礎設施或操作消息(即,屬於數據合同的消息),則連接會中止,因爲可能存在問題(一方崩潰,存在網絡問題等)。 )。

receiveTimeout是連接中止前未接收到操作消息的最大時間量(默認值爲10分鐘)。將此值設置爲較大的值(Int32.MaxValue位於24天附近的某個位置)可以保持連接不變,將inactivityTimeout設置爲較小的值(再次默認爲10分鐘)(時間小於最大值的2倍在網絡路由器將連接從不活動狀態中斷開之前)保持連接處於活動狀態。

WCF爲您處理所有這些事情。然後,您可以簡單地訂閱連接中止消息,以瞭解由於真正原因(應用程序崩潰,網絡超時,客戶端斷電等)何時斷開連接,並允許您重新創建連接。

此外,如果您不需要有序消息,請設置ordered="false",因爲這可以大大降低可靠會話的開銷。默認值是true。

注意:您可能不會收到連接中止事件,直到inactivityTimeout過期(或者您嘗試使用連接)。注意這一點,並相應地設置你的超時時間。

互聯網上的大多數建議是將receiveTimeout和inactivityTimeout都設置爲無限。這有兩個問題,第一個基礎設施消息沒有及時發送,所以路由器會斷開連接......迫使你做自己的keepalive。其次,大量非活動超時意味着它不會識別何時合法連接斷開,並且您必須依靠該中止來確定何時發生故障。這完全沒有必要,實際上甚至可能使您的服務更加不可靠。

+1

Thanks!從我讀的這個可靠會話和TCP協議本身一樣,但是在另一個級別上,這就是爲什麼我們將它設置爲enabled = false。如果我不使用可靠會話,我將需要自己的KeepAlive。這個KeepAlive變化很簡單,只需要每隔一段時間調用一個空的服務方法,讓我們說9分鐘,以確保連接是活的。如果它失敗了,那麼關閉應用程序。我可以在哪裏閱讀更多關於您發佈的所有信息?我之前查找過這些信息,但從未找到它。仍然不確定要設置哪些設置以及可以創建哪些開銷? – Banshee 2014-11-05 14:59:56

+0

@Banshee - 可靠的會話,如果按我剛纔提到的那樣進行適當的配置,將會是最少的開銷,也是最可靠的。通過關閉它並自己完成它,您可以將基本上是低級功能的東西強制到您的應用程序域中。通過自己做,你會失去重要的元數據,追蹤和診斷報告以及perfmon統計數據。換句話說,你正在使用高性能的賽車,並且將發動機拆下來,並在其中放置一個推車引擎,然後想知道爲什麼它不能執行。 – 2014-11-05 15:12:12

+0

@Banshee - 正如我所說,這是沒有很好的文件,並有很多錯誤信息。我在這裏所說的很難通過多年的反覆試驗,追蹤源代碼,閱讀各種矛盾的文檔並找出缺失的東西。可靠的會話,如我在這裏展示的那樣配置,工作得很好。但是你必須明確地知道它在做什麼,因爲文檔不完整,誤導,錯誤或不存在。 – 2014-11-05 15:13:56

0

根據我的經驗,我發現問題不一定是由WCF服務或配置引起的,而是客戶端自己的路由器。

以前我遇到過長時間停頓的問題,連接一段時間後仍然斷開。我相信一些路由器有一個機制來放棄它認爲不再活躍的連接,所以我唯一的解決方案是在服務上實現一個空方法並定期從客戶端調用它。

+1

顯然你沒有閱讀我的答案。我介紹了這種情況,以及它發生的原因(由於WCF服務配置錯誤)。是的,這是您的服務配置錯誤。保持活力的方法是解決你的配置錯誤的黑客。如果您正確配置路由器,WCF有一個機制來解決路由器超時問題。 – 2016-07-13 14:52:19