WCF回調(diào)操作是雞應(yīng)用技巧講解
WCF開發(fā)插件對(duì)于開發(fā)人員來說是一個(gè)比較重要的應(yīng)用工具,可以幫助我們輕松的實(shí)現(xiàn)一些特定的功能需求。在這里我們就一起來分享一下有關(guān)WCF回調(diào)操作的相關(guān)操作技巧。WCF回調(diào)操作簡(jiǎn)單的說就是由服務(wù)端來調(diào)用客戶端的方法,回調(diào)時(shí)原先的服務(wù)端和客戶端將發(fā)生對(duì)調(diào),服務(wù)端成為客戶端,客戶端成為服務(wù)端。#t#
WCF回調(diào)的必要條件:
1、并不是所有的綁定都支持回調(diào)操作,只有具有雙向通信能力的綁定才可以使用回調(diào)。比如HTTP是與連接無關(guān)的因此不能用于回調(diào)。這就說明我們不能使用BasicHttpBinding或WSHttpBinding進(jìn)行回調(diào)。WCF中NetTcpBinding和 NetNamedPipeBinding支持回調(diào),因?yàn)閺谋举|(zhì)上講TCP和IPC協(xié)議支持雙向通信。WCF中wsDualHttpBinding也是支持回調(diào)的因?yàn)樗鼘?shí)際上是設(shè)置了兩個(gè)HTTP通道
定義回調(diào)契約
一個(gè)服務(wù)契約若要定義回調(diào),必須專門定義一個(gè)用于回調(diào)的契約。一個(gè)服務(wù)契約最多包含一個(gè)回調(diào)契約,一個(gè)服務(wù)契約一旦定義了回調(diào)契約那客戶端必須支持這個(gè)WCF回調(diào)操作。那如何為一個(gè)服務(wù)契約定義回調(diào)呢?使用ServiceContract特性的CallBackContract特性,代碼如下:
- [ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
- public interface IService1
- {
- [OperationContract(IsOneWay=true)]
- void DoSomething();
- }
- //用于回調(diào)的契約
- interface ISomeCallbackContract
- {
- [OperationContract(IsOneWay=true)]
- void SomeCallbackMethod();
- [OperationContract(IsOneWay = true)]
- void SomeCallbackMethod2();
- }
客戶端WCF回調(diào)操作設(shè)置
客戶端需要實(shí)現(xiàn)服務(wù)端定義的那個(gè)用于回調(diào)的契約ISomeCallbackContract,然后實(shí)例化回調(diào)對(duì)象再通過它創(chuàng)建一個(gè)上下文對(duì)象InstanceContext。然后用代理把這個(gè)回調(diào)的引用傳回服務(wù)端
下面通過代碼實(shí)例說明:
服務(wù)端代碼:
- [ServiceContract(CallbackContract = typeof(ISomeCallbackContract))]
- public interface IService1
- {
- [OperationContract(IsOneWay=true)]
- void DoSomething();
- }
- //用于回調(diào)的契約
- interface ISomeCallbackContract
- {
- [OperationContract(IsOneWay=true)]
- void SomeCallbackMethod();
- [OperationContract(IsOneWay = true)]
- void SomeCallbackMethod2();
- }
實(shí)現(xiàn)服務(wù)的類:
- [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession,
ConcurrencyMode = ConcurrencyMode.Reentrant)]- public class Service1 : IService1
- {
- static List<ISomeCallbackContract> m_Callbacks = new
List<ISomeCallbackContract>();- public void DoSomething()
- {
- //獲得由客戶端傳入的回調(diào)終結(jié)點(diǎn)的引用,使用這個(gè)引用可以調(diào)用客戶端方法
- ISomeCallbackContract callback = OperationContext.Current.
GetCallbackChannel<ISomeCallbackContract>();- if (m_Callbacks.Contains(callback) == false)
- {
- m_Callbacks.Add(callback);
- }
- Trace.WriteLine("DoSomething");
- //調(diào)用客戶端實(shí)現(xiàn)的SomeCallbackMethod2方法,
- callback.SomeCallbackMethod2();
- CallClients();
- }
- static public void CallClients()
- {
- Action<ISomeCallbackContract> invoke =
delegate(ISomeCallbackContract callback)- {
- callback.SomeCallbackMethod();
- };
- m_Callbacks.ForEach(invoke);
- }
- }
客戶端代碼:
- //客戶端實(shí)現(xiàn)回調(diào)接口,使用VS自動(dòng)生成代理的時(shí)候,對(duì)于回調(diào)接口的命名默認(rèn)是
以服務(wù)契約接口名稱+Callback,而不是原先在服務(wù)端定義的回調(diào)接口的名子- public class CallBack : ServiceReferenceCallBack.IService1Callback
- {
- public void SomeCallbackMethod()
- {
- MessageBox.Show("SomeCallbackMethod()", "MyClient");
- }
- public void SomeCallbackMethod2()
- {
- MessageBox.Show("SomeCallbackMethod2()", "MyClient");
- }
- }
客戶端調(diào)用
首先生成回調(diào)接口實(shí)現(xiàn)的對(duì)象,然后用這個(gè)對(duì)象去實(shí)例化一個(gè)上下文對(duì)象context ,在創(chuàng)建客戶端代理對(duì)象的時(shí)候在構(gòu)造方法中使用這個(gè)上下文對(duì)象context 就可以把客戶端回調(diào)對(duì)象的引用作為消息的一部分傳送到服務(wù)端,在服務(wù)端就可以通過 OperationContext.Current.GetCallbackChannel<ISomeCallbackContract> ()來獲得這個(gè)回調(diào)對(duì)象的引用,服務(wù)端有了這個(gè)回調(diào)對(duì)象的引用就可以去調(diào)用客戶端實(shí)現(xiàn)的WCF回調(diào)操作方法。
- ServiceReferenceCallBack.IService1Callback callback = new CallBack();
- InstanceContext context = new InstanceContext(callback);
- ServiceReferenceCallBack.Service1Client sc = new
WCFPrograme.ServiceReferenceCallBack.Service1Client(context);- sc.DoSomething();


2009-12-22 19:14:36




