WCF开发工具的出现,几乎整合了.NET平台下所有的技术,为开发人员带来了非常大的好处。我们今天将会通过这篇文章介绍的内容充分的了解到有关WCF单向协定的相关创建方法,希望对大家有所帮助。#t#
创建WCF单向协定
通过将 ServiceContractAttribute 类应用到定义服务将要实现的方法的接口,创建服务协定。
通过将 OperationContractAttribute 类应用到相应的方法,指示客户端可以调用接口中的哪些方法。
通过将 IsOneWay 属性设置为 true,可将不得具有输出(没有返回值且没有 out 参数或 ref 参数)的操作指定为单向操作。注意,默认情况下,使用 OperationContractAttribute 类的操作都满足请求-答复协定,原因是默认情况下 IsOneWay 属性为 false。因此,如果需要对方法使用WCF单向协定,则必须将 attribute 属性的值显式指定为 true。
此示例演示具有单向服务操作的服务协定。客户端不会像在双向服务操作中那样等待服务操作完成。此示例基于入门示例并使用 wsHttpBinding 绑定。此示例中的服务是自承载控制台应用程序,通过它可以观察接收和处理请求的服务。客户端也是一个控制台应用程序。
注意:
本主题的末尾介绍了此示例的设置过程和生成说明。
若要创建单向服务协定,请定义服务协定,将 OperationContractAttribute 类应用于每个操作,并将 IsOneWay 设置为 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);
- }
为了演示客户端不会等待服务操作完成,此示例中的服务代码实现了五秒钟的延迟,如下面的示例代码所示:
- / 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);- }
- ...
- }
当客户端调用服务时,调用不等待服务操作完成即返回。
运行示例时,客户端和服务活动将显示在服务和客户端控制台窗口中。您可以看到服务从客户端接收消息。在每个控制台窗口中按 Enter 可以同时关闭服务和客户端。
客户端在服务之前完成,说明了客户端没有等待单向服务操作完成。客户端输出如下所示:
- Add(100,15.99)
- Subtract(145,76.54)
- Multiply(9,81.25)
- Divide(22,7)
- Press < ENTER> to terminate client.
服务输出如下所示:
- 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
在进行WCF单向协定时,需要注意:
HTTP 从定义上讲是一个请求/响应协议;当发出请求时,即返回响应。即使对于通过 HTTP 公开的单向服务操作,也是如此。当调用操作时,服务在执行服务操作之前返回 HTTP 状态码 202。此状态码表示请求已被接受进行处理,但处理尚未完成。调用操作的客户端在从服务收到 202 响应之前处于阻止状态。当使用绑定(配置为使用会话)发送多个单向消息时,这可能会产生某些意外行为。此示例中使用的 wsHttpBinding 绑定配置为默认使用会话来建立安全上下文。默认情况下,会话中的消息一定会按照它们的发送顺序到达。因此,当发送会话中的第二个消息时,在处理完***个消息之前不会处理第二个消息。这样的结果是,在处理完上一个消息之前,客户端不会收到消息的 202 响应。因此,客户端似乎是阻止了每个后续的操作调用。为了避免此行为,此示例对运行库进行了配置,以便将消息并发调度给不同的实例进行处理。此示例将 InstanceContextMode 设置为 PerCall,使每个消息可以由不同的实例来处理。ConcurrencyMode 设置为 Multiple,以允许多个线程同时调度消息。