最近在做開發的時候的遇到一個問題,採用WCF做服務端開發,利用的是TCP綁定。因為涉及到大資料量的傳輸,要求開啟可靠會話。
之前的程式中,本身是關閉了可靠會話,然後在伺服器端註冊了用戶端的Closing和Faulted事件:
OperationContext.Current.Channel.Closing += Exit;OperationContext.Current.Channel.Faulted += Exit;
程式運行正常,當用戶端出現網路異常中斷時(斷點,強制結束進程等),可以立即觸發事件,調用Exit方法。而當程式在receiveTimeout指定的時間段內,未產生過通訊,同樣也會觸發事件。這裡可以把receiveTimeout認為是一個空閑逾時。
但是在增加了可靠會話後,情況變得不一樣了。用戶端正常關閉時,可以立即觸發事件,但是異常中斷時,Closing和Faulted都沒有被觸發。Google了一下也沒有找到一個合理的解釋,那麼最有可能的原因是受到了inactivityTimeout的影響。
inactivityTimeout,MSDN上的解釋為:擷取或設定服務在關閉之前保持非使用中的時間間隔。
有點難以理解,於是做了一個實驗。
同樣一個服務,將receiveTimeout設定為1分鐘(預設10分鐘),將inactivityTimeout設定為10秒鐘,啟動用戶端調試。
如果調用伺服器端方法的時間間隔不超過1分鐘,那麼用戶端與伺服器將一直保持串連,直到1分鐘過後與用戶端主動中斷連線,則事件被觸發。
如果用戶端異常中斷連線(直接結束進程),則在5-10秒之後,事件被觸發。
PS:主動中斷連線或超過了receiveTimeout的設定值,只觸發Closing事件,如果是超過了inactivityTimeout設定值,還要額外觸發Faulted事件。
通過這個實驗,大概能理解receiveTimeout和inactivityTimeout的作用以及事件被觸發的時機了。
我個人的理解,receiveTimeout是指在用戶端和伺服器端保持串連的活動期間的空閑逾時值,如果在串連的活動期間,用戶端和伺服器端沒有資料互動,並且這個時間段超過了設定值,則伺服器會主動斷開用戶端的串連。
而inactivityTimeout則表示在用戶端和伺服器端已經斷開的情況下的非活動期間的空閑逾時值,如果在非活動期間,時間超過了設定值,則會觸發事件。
PS:inactivityTimout的時間設定如果超過receiveTimeout的話,是沒有意義的。
所以,如果想在用戶端斷開或異常斷開的時候立即觸發事件,則將inactivityTimout設定的盡量小,例如5秒,如果想讓用戶端和伺服器端保持長串連時,則將receiveTimeout設定的盡量大,例如1個小時。