一.单向通讯
单向操作不等同于异步操作,单向操作只是在发出调用的瞬间阻塞客户端,但如果发出多个单向调用,WCF会将请求调用放入到服务器端的队列中,并在某个时间进行执行。队列的存储个数有限,一旦发出的调用个数超出了队列容量,则会发生阻塞现象,此时调用请求无法放入队列,直到有其他请求被处理。
WCF中所有的绑定都支持单向通讯。
二.双向通讯
WCF请求-应答模式是WCF中默认的操作模式。应答的默认超时时间为1分钟,如果超过一分钟没有应答,客户端就会获得一个TimeOutException异常。WCF中除了NetPeerTcpBinding和NetMsmqBinding绑定,所有的绑定都支持请求-应答操作。
三.回调操作
WCF回调操作简单的说就是由服务器端来调用客户端的方法,回调时原先的服务端和客户端将发生对调,服务端成为客户端,客户端成为服务端。
WCF回调的必要条件:
并不是所有的绑定都支持回调操作,只有具有双向通讯能力的绑定才可以使用回调。比如HTTP是与连接无关的,因此不能用于回调。这就是说明我们不能使用BasicHttpBinding或WSHttpBinding进行回调。WCF中NetTcpBinding和NetNamedPipeBinding支持回调,因为从本质上讲TCP和IPC协议支持双向通信。WCF中wsDualHttpBinding也是支持回调的,因为它实际上是设置了两个HTTP通道,一个用于从客户端到服务的调用,另一个用于服务到客户端的调用。
回调操作时通过回调契约来实现的,回调契约属于服务契约的一部分,一个服务契约最多只能包含一个回调契约。一旦定义了回调契约,就需要客户端实现回调契约。在WCF中,可以通过ServiceContract的CallbackContract属性来定义回调契约。
以下是代码实现:
1.启用单向通讯的方法,不能有返回值(void可以),不能有out参数,只允许传入参数。
[ServiceContract(Namespace = "MyNamespace")] public interface IService { [OperationContract(IsOneWay = true)] void DoTestWork(string message); }
2.双向通讯是有问必有答的(哪怕方法返回void,客户端也会收到一条空消息)。
[ServiceContract(Namespace = "MyNamespace")] public interface IService { [OperationContract(IsOneWay = false)] DateTime DoTestWork(string message); }
3.回调操作代码实现
WCF服务端
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 [ServiceContract(Namespace="http://yxlblogs.cnblogs.com/WCF/Callback",CallbackContract=typeof(ICallback))] public interface IService1 { [OperationContract(IsOneWay = true)] void Add(int a,int b); } // 回调契约的定义,此时回调契约不需要应用ServiceContractAttribute特性 public interface ICallback { [OperationContract(IsOneWay=true)] void ShowResult(int a ,int b); } // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。 public class Service1 : IService1 { public void Add(int a, int b) { a++; b++; ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>(); // 对客户端操作进行回调 callback.ShowResult(a, b); } }
Web配置文件:
<system.serviceModel> <behaviors> <serviceBehaviors> <behavior> <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false --> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> <services> <service name="WcfService1.Service1"> <endpoint address="" binding="wsDualHttpBinding" contract="WcfService1.IService1"/> </service> </services> </system.serviceModel>
客户端调用:
class Program { private static void Main(string[] args) { InstanceContext instanceContext = new InstanceContext(new CallbackService()); Service1Client client = new Service1Client(instanceContext); client.Add(1, 2); Console.ReadKey(); } } // 客户端中对回调契约的实现 public class CallbackService : IService1Callback//生成的接口名为服务契约+Callback { public void ShowResult(int a, int b) { Console.WriteLine(a+b);//结果为5 } }