2009-08-15 154 views
1

我正在使用VSTS2008 + C#+ .Net 3.5開發IIS中託管的WCF服務。然後,我通過使用VSTS 2008中的添加服務引用功能自動生成客戶端代理代碼。WCF客戶端連接問題

我的問題是,假設我創建了一個客戶端代理實例,然後使用此特定實例調用服務器端WCF服務公開的各種方法。那麼,每次我進行方法調用時,它都會建立一個新的連接?或者客戶端和服務器之間會有連續的連接(即連接的生命週期是從創建客戶端代理實例到處理客戶端代理實例)?

我正在使用basicHttpBinding。

回答

0

連接被保留,直到代理被處置。

編輯

這將保持TCP連接開放,至少如果你使用可靠的消息。我的基礎是,如果TCP連接丟失,可靠的消息傳遞將失敗。請參閱:

http://codeidol.com/csharp/wcf/WCF-Essentials/Reliability/

EDIT 2

我收回對使用聲明的評論。請參閱:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

有點偏離主題,但我們已經使用添加服務引用停止,取而代之的是我們使用的方法在這裏描述:

http://www.dnrtv.com/default.aspx?showNum=103

注:這僅適用於如果您可以控制客戶端和服務器。

+0

謝謝,這是否意味着底層TCP連接保持打開(活動),直到代理處置? – George2 2009-08-15 18:03:21

+3

不,你不應該。在使用中包裝代理是一個糟糕的主意,好像Dispose在處於故障狀態的代理上被調用,然後它會拋出一個異常,從而首先隱藏導致錯誤的異常。 – blowdart 2009-08-15 18:16:16

+0

謝謝Shiraz,如果我沒有使用可靠的消息傳遞並且只使用basicHttpBinding的默認設置,底層連接是否會一直存在?或者每次我們調用一個方法都會有一個新的連接? – George2 2009-08-15 18:18:08

5

當底層信道關閉時,連接將被關閉 - 默認情況下,basicHttpBinding的與保持活動值,這使得客戶建立到支持它們服務持續連接消息發送連接HTTP標頭。

這並不意味着服務的一個實例保持活動狀態,只要連接到Web服務器(如果Web服務器支持它)。

如果你想連接到每一個呼叫後關閉,那麼你可以通過定義一個定製的結合從而

<services> 
<service> 
    <endpoint address="" 
     binding="customBinding" 
     bindingConfiguration="HttpBinding" 
     contract="IContract" /> 
</service> 
</services> 

<bindings> 
<customBinding> 
    <binding name="HttpBinding" keepAliveEnabled="False"/> 
</customBinding> 
</bindings> 

連接關閉它在服務器端將關閉根據您的代理是如何長掛周圍,如果需要,生成的代理將重新打開它。

+0

謝謝!兩個混淆,1。「這並不意味着服務的一個實例保持活着」 - 你是什麼意思「服務的一個實例是活着的」? 2.「如果網絡服務器支持它。」 - 對於IIS,如何檢查是否支持? – George2 2009-08-16 05:13:14

+0

對不起2個更多的混淆, 3.「和生成的代理將重新打開它,如果需要。」 - 底層WCF將自動處理它,並且如果連接關閉並再次重新打開,則不會拋出異常?開發人員無需處理這種情況? 4.「連接將關閉,取決於代理掛起的時間」 - 是否可配置? – George2 2009-08-16 05:14:48

+1

「服務實例」是指實現服務合約的類的Web服務器計算機上的實例。有些人認爲在創建代理實例時會創建服務實例。這不是真的。 – 2009-08-16 05:18:22

2

喬治,要考慮的一件事是,你的代碼應該儘量不關心連接打開或關閉的方式,時間或時間。這主要是渠道關注的問題,渠道應該能夠在合適的情況下管理連接,而不必擔心自己編寫的代碼取決於渠道「如何管理自己的業務」。

只有當您看到或懷疑性能問題時,才應該擔心這樣的實現細節。如果您擔心可能存在此類問題,請創建一個概念應用程序的快速證明,並使用Fiddler或其他工具觀察網絡流量。在大多數情況下,這將浪費時間。

+0

謝謝約翰,我完全同意你的看法。目前我在將大量數據從服務器傳輸到客戶端時遇到了一個問題。這是我的問題,http://stackoverflow.com/questions/1281269/response-size-limitaiton-of-a-wcf-web-serivces我懷疑openTimeout參數是否導致這個問題,我想我需要知道每次我進行方法調用時是否需要建立連接或者只需打開一次。如果只打開一次,這個參數不應該引起這個問題,因爲我在這個錯誤方法調用之前做了一些成功的方法調用,但是如果每次連接都需要建立 – George2 2009-08-16 05:37:55

+0

(續),我認爲這個參數可能會影響結果。對於這個參數的任何註釋,或者每次方法調用發生或只發生一次連接是否需要建立? – George2 2009-08-16 05:38:36

+1

即使需要多次建立自己,每次都會使用配置的參數。 – 2009-08-16 05:42:42

3

然後,每次我做一個方法調用它會建立一個新的連接?

是的,這是默認行爲和首選行爲 - 它可以爲您節省很多的痛苦!

「這並不意味着該服務的一個實例保持活動狀態」 - 你什麼你的意思是「服務的一個實例保持活動狀態」?

在默認和「每呼叫」服務優先的情況下,這是發生了什麼:

  • 客戶端代理髮出調用服務
  • 的消息是序列化在客戶端並通過電話線
  • 發送,服務器端有一個「通道監聽器」,它將接收該消息並查看哪個服務類將處理呼叫
  • 服務器端的消息調度器將實例化一個「YourServiceClass」實例,服務器端的消息調度程序現在將在新創建的服務類實例上調用該方法,並獲取結果並將其打包,以便解析
  • 在服務器端的服務類對象被釋放
  • 響應發送回客戶端

這就是你的服務類應儘可能瘦的原因之一,因爲別的儘可能獨立 - 他們通常會爲每個進入的請求實例化,然後釋放。

這似乎是一個非常糟糕的主意 - 但如果服務對象實例徘徊了很長時間,則必須進行大量的簿記才能跟蹤其狀態等等,因此在最後,它實際上更容易(並且通常更安全和更簡單)來創建服務類,讓它處理請求,然後再次釋放它。

Marc

+0

嗨,馬克,我很困惑。從與blowdart的討論看來,似乎保持活力是默認行爲,如果保持活躍狀態​​,則在我們進行第一次方法調用時應該只建立一次連接,而在每次進行方法調用時都不會打開/關閉。任何意見? – George2 2009-08-17 12:33:55