WCF響應(yīng)服務(wù)基本應(yīng)用技巧分享
WCF中有很多比較有用的應(yīng)用技巧,需要我們在不斷的學(xué)習(xí)和實(shí)踐中去積累經(jīng)驗(yàn),來達(dá)到一個(gè)熟練操作的程度。在這里我們就先為大家詳細(xì)介紹一下有關(guān)WCF響應(yīng)服務(wù)的一些基本應(yīng)用技術(shù),希望能給大家?guī)硪恍椭?t#
到目前為止,我們所介紹的排隊(duì)調(diào)用的編程模型是單側(cè)的:客戶端向隊(duì)列發(fā)布單向消息,再由服務(wù)處理該消息。如果排隊(duì)的操作真的就是單向調(diào)用,那么這種模型足以滿足要求。然而,排隊(duì)服務(wù)有時(shí)候需要反過來向其客戶端報(bào)告調(diào)用的結(jié)果、返回的結(jié)果,甚至是錯(cuò)誤。但在默認(rèn)情況下,這是無法實(shí)現(xiàn)的。Windows Communication Foundation 將排隊(duì)調(diào)用與單向調(diào)用等同起來,而單向調(diào)用在本質(zhì)上是禁止任何此類響應(yīng)的。此外,排隊(duì)服務(wù)(及其客戶端)可能未處于連接狀態(tài)。如果客戶端發(fā)布對未連接服務(wù)的排隊(duì)調(diào)用,則當(dāng)服務(wù)最終獲得并處理這些消息時(shí),可能不會(huì)有客戶端來接收值,因?yàn)榭蛻舳丝赡茉缫央x線了。這一問題的解決方案是讓服務(wù)將報(bào)告返回給客戶端所提供的排隊(duì)服務(wù)。我將此類服務(wù)稱作WCF響應(yīng)服務(wù)。
響應(yīng)服務(wù)就是系統(tǒng)中的另一個(gè)排隊(duì)服務(wù)。它同樣可能與客戶端斷開連接并由單獨(dú)的進(jìn)程或單獨(dú)的計(jì)算機(jī)進(jìn)行托管,或者它也可能共享客戶端的進(jìn)程。如果響應(yīng)服務(wù)共享客戶端的進(jìn)程,則當(dāng)客戶端啟動(dòng)時(shí),響應(yīng)服務(wù)即開始處理排隊(duì)的響應(yīng)。將響應(yīng)服務(wù)由獨(dú)立于客戶端的進(jìn)程(甚至是計(jì)算機(jī))托管有助于進(jìn)一步將響應(yīng)服務(wù)的生存期與使用該響應(yīng)服務(wù)的客戶端相分離。
設(shè)計(jì)WCF響應(yīng)服務(wù)合約
就如使用任何 Windows Communication Foundation 服務(wù)一樣,客戶端和服務(wù)需要預(yù)先商定響應(yīng)合約及其適用對象(例如返回的值和錯(cuò)誤信息,或僅僅是返回的值)。請注意,您也可將響應(yīng)服務(wù)拆分為兩個(gè)服務(wù),一個(gè)用于響應(yīng)結(jié)果,另一個(gè)用于響應(yīng)錯(cuò)誤。例如,假定有如下由排隊(duì) MyCalculator 服務(wù)所實(shí)現(xiàn)的 ICalculator 合約:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract(IsOneWay = true)]
- void Add(int number1,int number2);
- ... //更多操作
- }
- [ServiceBehavior(InstanceContextModeInstanceContextMode =
- InstanceContextMode.PerCall)]
- class MyCalculator : ICalculator {...}
要求 MyCalculator 服務(wù)以計(jì)算結(jié)果來響應(yīng)客戶端并報(bào)告所有錯(cuò)誤。計(jì)算結(jié)果為整數(shù)形式,錯(cuò)誤以 Windows Communication Foundation ExceptionDetail 數(shù)據(jù)合約形式表示。對于響應(yīng)服務(wù),可按下列方式定義 ICalculatorResponse 合約:
- [ServiceContract]
- interface ICalculatorResponse
- {
- [OperationContract(IsOneWay = true)]
- void OnAddCompleted(int result,ExceptionDetail error);
- }
支持 ICalculatorResponse 的WCF響應(yīng)服務(wù)需要檢查返回的錯(cuò)誤信息,在方法結(jié)束時(shí)通知客戶端應(yīng)用程序、用戶或應(yīng)用程序管理員,并將結(jié)果提供給相關(guān)方。下面是一個(gè)支持 IcalculatorResponse 的簡單響應(yīng)服務(wù):
- [ServiceBehavior(InstanceContextModeInstanceContextMode =
InstanceContextMode.PerCall)]- class MyCalculatorResponse : ICalculatorResponse
- {
- [OperationBehavior(TransactionScopeRequired = true)]
- public void OnAddCompleted(int result,ExceptionDetail error)
- {
- MessageBox.Show("結(jié)果 = " + result,"MyCalculatorResponse");
- if(error != null)
- {
- //處理錯(cuò)誤
- }
- }
- }
實(shí)現(xiàn) MyCalculator 和 MyCalculatorResponse 會(huì)直接引出兩個(gè)問題。***個(gè)問題是同一響應(yīng)服務(wù)可能會(huì)被用于處理多個(gè)排隊(duì)服務(wù)上多個(gè)調(diào)用的響應(yīng)(或完成),而 MyCalculatorResponse(更重要的是其所服務(wù)的客戶端)無法區(qū)分這些響應(yīng)。這一問題的解決方案是讓發(fā)出原始排隊(duì)調(diào)用的客戶端向該調(diào)用分配某個(gè)***的 ID 作為標(biāo)記。排隊(duì)服務(wù) MyCalculator 需要將該 ID 傳遞給 MyCalculatorResponse,使其能夠應(yīng)用與該 ID 相關(guān)的某種自定義邏輯。
第二個(gè)問題是排隊(duì)服務(wù)如何發(fā)現(xiàn)WCF響應(yīng)服務(wù)的地址。與雙向回調(diào)不同的是,Windows Communication Foundation 內(nèi)部并不支持將響應(yīng)服務(wù)引用傳遞給服務(wù)。而將該地址放入服務(wù)主機(jī)配置文件中(客戶端一節(jié)中)并不是明智之舉,因?yàn)橥慌抨?duì)服務(wù)可能會(huì)被多個(gè)客戶端調(diào)用,而每個(gè)客戶端都有其自身專用的響應(yīng)服務(wù)和地址。
一種可能的解決方案是將客戶端所管理的 ID 和所需的響應(yīng)服務(wù)地址作為參數(shù)基于排隊(duì)服務(wù)合約明確傳遞給每個(gè)操作:
- [ServiceContract]
- interface ICalculator
- {
- [OperationContract(IsOneWay = true)]
- void Add(int number1,int number2,
- string responseAddress,string methodID);
- }
同樣,排隊(duì)服務(wù)也可以將WCF響應(yīng)服務(wù)的方法 ID 作為參數(shù)基于排隊(duì)響應(yīng)合約明確傳遞給每個(gè)操作:
- [ServiceContract]
- interface ICalculatorResponse
- {
- [OperationContract(IsOneWay = true)]
- void OnAddCompleted(int result,ExceptionDetail error,
- string methodID);
- }