昨天終於下定決心計劃這個月要把WCF學完,之所以安排一個月的時間,我不要只是學些表面的東西,我要比較深入的去學習下它。如果只學些表面的東西,我想一般的人花個一周的時間就夠了。最近一段時間想要學的東西感覺太多了,想學習下Silverlight、WPF、WCF、MVC等,但總感覺好像很忙似的,我也不知道我在忙些什麼,就這樣稀裡糊塗的一天就過去,一事無成。昨天晚上終於想起了5月份寫的一個計劃規則,還是按照這個計劃規則去寫每天的計劃、日記、月計劃。這樣每天做了些什麼,每天應該做些什麼,目標很明確,再也不會像以前那樣,想學Silverlight、WPF、WCF、MVC等,一會兒想看下Silverlight,一會兒想看下WPF,一會兒想等找到份工作再去學習它們。像這樣下去這些東西的皮毛都沒有學到,而且這樣又把自己累得要死。 人們總喜歡說計劃趕不變化,我覺得這沒有什麼道理,我覺得只要你計劃的合理的話,這個計劃肯定不會難產的。這是我最近的狀況總結。費話說的有點多了,還大家見諒。。。呵呵!下面主要是和大家分享下我今天所學的雙工模式。
這個其實不難,但讓我花比較長的時間,咱天生有點愚笨,沒辦法,所以特意記錄下,以免下次又忘記了。
雙工模式的特點是:無論使用單向訊息發送還是請求/回覆訊息發送方式,服務和用戶端均能夠獨立地向對方發送訊息。對於必須直接與用戶端通訊或向訊息交換的任意一方提供非同步體驗(包括類似於事件的行為)的服務來說,這種雙向通訊形式非常有用。
由於存在與用戶端通訊的附加機制,雙工模式比請求/回覆或單向模式要略為複雜。
若要設計為雙向合約,還必須設計回調協定,並將該回調協定的類型分配給標記服務合約的ServiceContractAttribute屬性(attribute)的CallbackContract屬性(protery)。
若要實現雙工模式,您必須建立第二個介面,該介面包含在用戶端調用的方法聲明。(以上四段話摘自:MSDN Webcasts 徐長龍講的《跟我一起從零開始學WCF系列課程》的第二章,希望大家能充分理解這四段的意思,我今花了比較長的時間來學這個雙工模式,就是因為沒有注意看這四段話,沒有理解好。)。
下面我們就來建立一個WCF項目吧!
點擊確定,就這樣建立了一個WCF項目了。簡單吧。。。
目錄如下:
你把IService1.cs和Serivce1.cs刪除了也可以,沒事的,咱就懶得刪除了。咱把IService1.cs和Serivce1.cs裡面的內容全部刪除了。以下是IService1.cs檔案裡的內容:
namespace WcfServiceLibrary4{ [ServiceContract(Namespace = "http://Microsoft.ServiceMode.Samples", SessionMode = SessionMode.Required, CallbackContract = typeof(IB))] //定義一個服務介面 public interface IA { [OperationContract(IsOneWay=true)] void Clear(); } //這個是服務端調用用戶端裡方法的一個介面,在用戶端裡寫一個類繼承這個介面時,你是找到不IB這個介面的名字的,上面的CallbackContract = typeof(IB)這句話指定的回調的介面是IB,但它是以IACallback的形式出現的 public interface IB { [OperationContract(IsOneWay=true)] void E(double e); }}
以下是Serivce1.cs裡面的代碼:
namespace WcfServiceLibrary4{ [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)] public class A : IA { double result; //聲明一個IB介面的對象 IB ib = null; //A類的構造方法 public A() { result = 0.0D; //執行個體化一個IB ib = OperationContext.Current.GetCallbackChannel<IB>(); } public void Clear() { //服務端調用用戶端的E方法 ib.E(result + 9); } }}
然後把App.config設定檔修改下就可以了。
本來是這樣的:
<service name="WcfServiceLibrary4.Service1" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/Service1/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否則地址將與上面提供的基址相關 --> <endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary4.IService1">
修改後:
<service name="WcfServiceLibrary4.A" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/A/" /> </baseAddresses> </host> <!-- Service Endpoints --> <!-- 除非完全限定,否則地址將與上面提供的基址相關 --> <endpoint address ="" binding="wsDualHttpBinding" contract="WcfServiceLibrary3.IA">
一定要把wsHttpBinding改成wsDualHttpBinding,請大家仔細對照下。
下面實現用戶端的調用吧,不過端還得實現服務端IB的介面。
我在這個項目裡添加了個命令項目,你添加個WebFrom項目或者Windows項目也可以的。
哦,差點忘了應該先產生下服務,然後再在命令項目裡右擊“引用”選擇“加入服務參考",不要點錯了哦。
然後我們開始在Program.cs裡添加如下代碼:
//請記得添加以下兩個命名空間using System.ServiceModel;using ConsoleApplication1.ServiceReference1;namespace ConsoleApplication1{ /// <summary> /// 我今天主要是在B繼承一個介面這個花了很長的時間,我總以為能找到服務端裡的IB介面,誰知道服務端的介面IB是IACallback的形式出現在用戶端 /// </summary> public class B:IACallback { #region IACallback 成員 //實現了IB介面的E方法 public void E(double e1) { Console.WriteLine("E:" + e1); }#endregion } class Program { static void Main(string[] args) { InstanceContext instanceContext = new InstanceContext(new B()); ServiceReference1.AClient client = new AClient(instanceContext); client.Clear(); Console.ReadKey(); } }}
Demo下載
歡迎大家拍磚,咱家正在建房......,如果你是燒磚廠的,歡迎你一車磚一車磚的拍,咱高興的很呐,時間也不早了,明天早上還要去面試,該洗洗睡了,晚安各位基友。。。