WCF單向協(xié)定基本創(chuàng)建步驟解析
WCF開發(fā)工具的出現(xiàn),幾乎整合了.NET平臺(tái)下所有的技術(shù),為開發(fā)人員帶來了非常大的好處。我們今天將會(huì)通過這篇文章介紹的內(nèi)容充分的了解到有關(guān)WCF單向協(xié)定的相關(guān)創(chuàng)建方法,希望對(duì)大家有所幫助。#t#
創(chuàng)建WCF單向協(xié)定
通過將 ServiceContractAttribute 類應(yīng)用到定義服務(wù)將要實(shí)現(xiàn)的方法的接口,創(chuàng)建服務(wù)協(xié)定。
通過將 OperationContractAttribute 類應(yīng)用到相應(yīng)的方法,指示客戶端可以調(diào)用接口中的哪些方法。
通過將 IsOneWay 屬性設(shè)置為 true,可將不得具有輸出(沒有返回值且沒有 out 參數(shù)或 ref 參數(shù))的操作指定為單向操作。注意,默認(rèn)情況下,使用 OperationContractAttribute 類的操作都滿足請(qǐng)求-答復(fù)協(xié)定,原因是默認(rèn)情況下 IsOneWay 屬性為 false。因此,如果需要對(duì)方法使用WCF單向協(xié)定,則必須將 attribute 屬性的值顯式指定為 true。
此示例演示具有單向服務(wù)操作的服務(wù)協(xié)定??蛻舳瞬粫?huì)像在雙向服務(wù)操作中那樣等待服務(wù)操作完成。此示例基于入門示例并使用 wsHttpBinding 綁定。此示例中的服務(wù)是自承載控制臺(tái)應(yīng)用程序,通過它可以觀察接收和處理請(qǐng)求的服務(wù)。客戶端也是一個(gè)控制臺(tái)應(yīng)用程序。
注意:
本主題的末尾介紹了此示例的設(shè)置過程和生成說明。
若要?jiǎng)?chuàng)建單向服務(wù)協(xié)定,請(qǐng)定義服務(wù)協(xié)定,將 OperationContractAttribute 類應(yīng)用于每個(gè)操作,并將 IsOneWay 設(shè)置為 true,如下面的示例代碼所示:
- [ServiceContract(Namespace="http://Microsoft.
ServiceModel.Samples")]- public interface IOneWayCalculator
- {
- [OperationContract(IsOneWay=true)]
- void Add(double n1, double n2);
- [OperationContract(IsOneWay = true)]
- void Subtract(double n1, double n2);
- [OperationContract(IsOneWay = true)]
- void Multiply(double n1, double n2);
- [OperationContract(IsOneWay = true)]
- void Divide(double n1, double n2);
- }
為了演示客戶端不會(huì)等待服務(wù)操作完成,此示例中的服務(wù)代碼實(shí)現(xiàn)了五秒鐘的延遲,如下面的示例代碼所示:
- / This service class implements the service contract.
- // This code writes output to the console window.
- [ServiceBehavior(ConcurrencyModeConcurrencyMode =
ConcurrencyMode.Multiple, InstanceContextModeInstanceContextMode
= InstanceContextMode.PerCall)]- public class CalculatorService : IOneWayCalculator
- {
- public void Add(double n1, double n2)
- {
- Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
- System.Threading.Thread.Sleep(1000 * 5);
- double result = n1 + n2;
- Console.WriteLine("Processing Add({0},{1}) - result:
{2}", n1, n2, result);- }
- ...
- }
當(dāng)客戶端調(diào)用服務(wù)時(shí),調(diào)用不等待服務(wù)操作完成即返回。
運(yùn)行示例時(shí),客戶端和服務(wù)活動(dòng)將顯示在服務(wù)和客戶端控制臺(tái)窗口中。您可以看到服務(wù)從客戶端接收消息。在每個(gè)控制臺(tái)窗口中按 Enter 可以同時(shí)關(guān)閉服務(wù)和客戶端。
客戶端在服務(wù)之前完成,說明了客戶端沒有等待單向服務(wù)操作完成??蛻舳溯敵鋈缦滤荆?/p>
- Add(100,15.99)
- Subtract(145,76.54)
- Multiply(9,81.25)
- Divide(22,7)
- Press < ENTER> to terminate client.
服務(wù)輸出如下所示:
- The service is ready.
- Press < ENTER> to terminate service.
- Received Add(100,15.99) - sleeping
- Received Subtract(145,76.54) - sleeping
- Received Multiply(9,81.25) - sleeping
- Received Divide(22,7) - sleeping
- Processing Add(100,15.99) - result: 115.99
- Processing Subtract(145,76.54) - result: 68.46
- Processing Multiply(9,81.25) - result: 731.25
- Processing Divide(22,7) - result: 3.14285714285714
在進(jìn)行WCF單向協(xié)定時(shí),需要注意:
HTTP 從定義上講是一個(gè)請(qǐng)求/響應(yīng)協(xié)議;當(dāng)發(fā)出請(qǐng)求時(shí),即返回響應(yīng)。即使對(duì)于通過 HTTP 公開的單向服務(wù)操作,也是如此。當(dāng)調(diào)用操作時(shí),服務(wù)在執(zhí)行服務(wù)操作之前返回 HTTP 狀態(tài)碼 202。此狀態(tài)碼表示請(qǐng)求已被接受進(jìn)行處理,但處理尚未完成。調(diào)用操作的客戶端在從服務(wù)收到 202 響應(yīng)之前處于阻止?fàn)顟B(tài)。當(dāng)使用綁定(配置為使用會(huì)話)發(fā)送多個(gè)單向消息時(shí),這可能會(huì)產(chǎn)生某些意外行為。此示例中使用的 wsHttpBinding 綁定配置為默認(rèn)使用會(huì)話來建立安全上下文。默認(rèn)情況下,會(huì)話中的消息一定會(huì)按照它們的發(fā)送順序到達(dá)。因此,當(dāng)發(fā)送會(huì)話中的第二個(gè)消息時(shí),在處理完***個(gè)消息之前不會(huì)處理第二個(gè)消息。這樣的結(jié)果是,在處理完上一個(gè)消息之前,客戶端不會(huì)收到消息的 202 響應(yīng)。因此,客戶端似乎是阻止了每個(gè)后續(xù)的操作調(diào)用。為了避免此行為,此示例對(duì)運(yùn)行庫進(jìn)行了配置,以便將消息并發(fā)調(diào)度給不同的實(shí)例進(jìn)行處理。此示例將 InstanceContextMode 設(shè)置為 PerCall,使每個(gè)消息可以由不同的實(shí)例來處理。ConcurrencyMode 設(shè)置為 Multiple,以允許多個(gè)線程同時(shí)調(diào)度消息。