跟我一起学WCF(9)——WCF回调操作的实现

一、引言

  在上一篇文章中介绍了WCF对Session的支持,在这篇文章中将详细介绍WCF支持的操作。在WCF中,除了支持经典的请求/应答模式外,还提供了对单向操作、双向回调操作模式的支持,此外还有流操作的支持。接下来将详细介绍下这几种操作,并实现一个双向回调操作的例子。

二、WCF操作详解

2.1 请求—应答操作

  请求应答模式是WCF中默认的操作模式。请求应答模式指的是:客户端以消息形式发送请求,它会阻塞客户端直到收到应答消息。应答的默认超时时间为1分钟,如果超过这一时间服务仍然没有应答,客户端就会获得一个TimeOutException异常。WCF中除了NetPeerTcpBinding和NetMsmqBinding绑定,所有的绑定都支持请求—应答操作。

2.2 单向操作

  单向操作是没有返回值的,客户端不关心调用是否成功。单向操作指的是:客户端一旦发出调用请求,WCF会生成一个请求消息发送给服务端,但客户端并不需要接收相关的应答消息。因此,单向操作不能有返回值,并且服务端抛出的任何异常都不会传递给客户端。所以客户端如果需要捕获服务端发生的异常,此时不能把操作契约的IsOneWay属性设置为true,该属性的默认值为false。异常处理参考:如何在WCF进行Exception Handling。单向操作不等同于异步操作,单向操作只是在发出调用的瞬间阻塞客户端,但如果发出多个单向调用,WCF会将请求调用放入服务端的队列中,并在某个时间进行执行。队列的存储个数有限,一旦发出的调用个数超出了队列容量,则会发生阻塞现象,此时调用请求无法放入丁烈,直到有其他请求被处理,即队列中的请求出队列后,产生阻塞的调用就会放入队列,并解除对客户端的阻塞。WCF中所有绑定都支持单向操作。WCF中实现单向操作只需要设置IsOneWay属性为true即可。这里需要注意一点:由于单向操作没有应答消息,因此它不能包含返回结果。

2.3 回调操作

  WCF支持服务将调用返回给它的客户端。在回调期间,服务成为了客户端,而客户端成为了服务。在WCF中,并不是所有的绑定都支持回调操作,只有具有双向能力的绑定才能够用于回调。例如,HTTP本质上是与连接无关的,所以它不能用于回调,因此我们不能基于basicHttpBinding和wsHttpBinding绑定使用回调,WCF为NetTcpBinding和NetNamedPipeBinding提供了对回调的支持,因为TCP和IPC协议都支持双向通信。为了让Http支持回调,WCF提供了WsDualHttpBinding绑定,它实际上设置了两个Http通道:一个用于从客户端到服务的调用,另一个用于服务到客户端的调用。

  回调操作时通过回调契约来实现的,回调契约属于服务契约的一部分,一个服务契约最多只能包含一个回调契约。一旦定义了回调契约,就需要客户端实现回调契约。在WCF中,可以通过ServiceContract的CallbackContract属性来定义回调契约。具体的实现代码如下所示:

// 指定回调契约为ICallback
    [ServiceContract(Namespace="http://cnblog.com/zhili/", CallbackContract=typeof(ICallback))]
    public interface ICalculator
    {
        [OperationContract(IsOneWay = true)]
        void Multiple(double a, double b);
    }

// 回调契约的定义,此时回调契约不需要应用ServiceContractAttribute特性
    public interface ICallback
    {
        [OperationContract(IsOneWay = true)]
        void DisplayResult(double x, double y, double result);
    }

  在上面代码中,回调契约不必标记ServiceContract特性,因为类型只要被定义为回调契约,就代表它具有ServiceContract特性,但仍然需要为所有的回调接口中的方法标记OperationContract特性。

2.4 流操作

  在默认情况下,当客户端与服务交换消息时,这些消息会被放入到接收端的缓存中,一旦接收到完整的消息,就立即被传递处理。无论是客户端发送消息到服务还是服务返回消息给客户端,都是如此。当客户端调用服务时,只要接收到完整的消息,服务就会被调用,当包含了调用结果的返回消息被客户端完整接收时,才会接触对客户端的阻塞。对于数据量小的消息,这种交换模式提供了简单的编程模型,因为接收消息的耗时较短,然而,一旦处理数据量更大的消息,例如包含了多媒体内容或大文件,如果每次都要等到完整地接收消息之后才能解除阻塞,这未免也不现实。为了解决这样的问题,WCF允许接收端通过通道接收消息的同时,启动对消息数据的处理,这样的处理过程称为流传输模型。对于具有大量负载的消息而言,流操作改善了系统的吞吐量和响应速度,因为在发生和接收消息的同时,不管是发送端还是接收端都不会被阻塞。

三、WCF中回调操作的实现

  上面介绍了WCF中支持的四种操作,下面就具体看看WCF中回调操作的实现。该例子的基本原理是:客户端调用服务操作,服务操作通过客户端上下文实例调用客户端操作。下面还是按照三个步骤来实现该WCF程序。

  第一步:同样是实现WCF服务契约和契约的实现。具体的实现代码如下所示:

 1 // 指定回调契约为ICallback
 2     [ServiceContract(Namespace="http://cnblog.com/zhili/", CallbackContract=typeof(ICallback))]
 3     public interface ICalculator
 4     {
 5         [OperationContract(IsOneWay = true)]
 6         void Multiple(double a, double b);
 7     }
 8
 9  // 回调契约的定义,此时回调契约不需要应用ServiceContractAttribute特性
10     public interface ICallback
11     {
12         [OperationContract(IsOneWay = true)]
13         void DisplayResult(double x, double y, double result);
14     }
15
16  // 服务契约的实现
17     public class CalculatorService : ICalculator
18     {
19         #region ICalculator Members
20         public void Multiple(double a, double b)
21         {
22             double result = a * b;
23             // 通过客户端实例通道
24             ICallback callback = OperationContext.Current.GetCallbackChannel<ICallback>();
25
26             // 对客户端操作进行回调
27             callback.DisplayResult(a, b, result);
28         }
29         #endregion
30     }

  第二步:实现服务宿主。这里还是以控制台程序作为服务宿主。具体的实现代码如下所示:

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
 6             {
 7                 host.Opened += delegate
 8                 {
 9                     Console.WriteLine("Service start now....");
10                 };
11
12                 host.Open();
13                 Console.Read();
14             }
15         }
16     }

  宿主对应的配置文件内容如下所示:

<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Metadata"/>
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service name="WCFContractAndService.CalculatorService">
                <endpoint address="net.tcp://localhost:9003/CalculatorService" binding="netTcpBinding" contract="WCFContractAndService.ICalculator"/>
            </service>
        </services>
    </system.serviceModel>
</configuration>

  第三步:实现客户端。由于服务端来对客户端操作进行回调,所以此时客户端需要实现回调契约。首先以管理员权限启动服务宿主,服务宿主启动成功之后,客户端通过添加服务引用的方式来生成客户端代理类,此时需要在添加服务引用窗口地址中输入:http://localhost:8080/Metadata。添加服务引用成功之后,接着在客户端实现回调契约,具体的实现代码如下所示:

1 // 客户端中对回调契约的实现
2     public class CallbackWCFService : ICalculatorCallback
3     {
4         public void DisplayResult(double a, double b, double result)
5         {
6             Console.WriteLine("{0} * {1} = {2}", a, b, result);
7         }
8     }

  接下来就是实现测试回调操作的客户端代码了。具体的实现步骤是:实例化一个回调类的实例,然后把它作为上下文实例的操作,最后把上下文实例作为客户端代理的参数来实例化客户端代理。具体的实现代码如下所示:

 1  // 客户端实现,测试回调操作
 2     class Program
 3     {
 4         static void Main(string[] args)
 5         {
 6             InstanceContext instanceContex = new InstanceContext(new CallbackWCFService());
 7             CalculatorClient proxy = new CalculatorClient(instanceContex);
 8             proxy.Multiple(2,3);
 9
10             Console.Read();
11         }
12     }

  下面运行运行该程序来检测下该程序是否能够成功回调,首先以管理员权限启动服务宿主程序,再启动客户端程序,如果回调成功,你将看到如下图所示的运行结果:

  这里只是演示了回调操作的实现,关于流操作的实现,这里就不再去实现了,等具体需要的时候再去研究吧,同时给出关于流操作实现的参考文章:

  Stream Operation in WCF

WCF流处理(Streaming)机制

四、总结

  到这里,WCF操作的内容就分享结束了,本文首先介绍了在WCF中支持四种操作:请求-应答操作、单向操作、回调操作和流操作,WCF中默认的操作时请求-应答操作,最后实现了一个回调操作的实例。

  本文所有源码:WCFCallbackOperation.zip

时间: 2024-08-25 01:53:05

跟我一起学WCF(9)——WCF回调操作的实现的相关文章

跟我一起学WCF(13)——WCF系列总结

引言 WCF是微软为了实现SOA的框架,它是对微乳之前多种分布式技术的继承和扩展,这些技术包括Enterprise Service..NET Remoting.XML Web Service.MSMQ等.WCF推出的原因在于:微软想将不同的分布式技术整合起来,提供一个统一的编程模型,这样对于开发者来说绝对是好事.在过去的2个月时间内,我陆续写了WCF系列文章,这些文章只是自己这段时间学习WCF内容的一个学习过程和笔记,希望通过这种写博文的方式记录下来和总结.本系列并没有对WCF机制做一个深入解析

Wcf使用Net.Tcp做回调操作

契约: [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required, CallbackContract = typeof(ITransferCallback))] 如果要使用回调,必须加上这句话 public interface IMonitorService { [OperationContract(IsOneWay = true)]

WCF分布式开发步步为赢(10):请求应答(Request-Reply)、单向操作(One-Way)、回调操作(Call Back).

WCF除了支持经典的请求应答(Request-Reply)模式外,还提供了什么操作调用模式,他们有什么不同以及我们如何在开发中使用这些操作调用模式.今天本节文章里会详细介绍.WCF分布式开发步步为赢(10):请求应答(Request-Reply).单向操作(One-Way).回调操作(Call Back).本文结构:[1]请求应答(Request-Reply).[2]单向操作(One-Way).[3]回调操作(Call Back).[4]示例代码分析.[5]总结.最后上传本文的示例代码. WCF

跟我一起学WCF(12)——WCF中Rest服务入门

一.引言 要将Rest与.NET Framework 3.0配合使用,还需要构建基础架构的一些部件.在.NET Framework 3.5中,WCF在System.ServiceModel.Web组件中新增了编程模型和这些基础架构部件. 新编程模型有两个主要的新属性:WebGetAttribute和WebInvokeAttribute,还有一个URI模板机制,帮助你声明每种方法响应使用的URI和动词..NET Framework还提供了一个新的绑定(WebHttpBinding)和新的行为(We

跟我一起学WCF(7)——WCF数据契约与序列化详解

一.引言 在前面博文介绍到,WCF的契约包括操作契约.数据契约.消息契约和错误契约,前面一篇博文已经结束了操作契约的介绍,接下来自然就是介绍数据契约了.所以本文要分享的内容就是数据契约. 二.数据契约的介绍 在WCF中,服务契约定义了可供调用的服务操作方法,而数据契约则是定义了服务端和客户端之间传送的自定义类型,在WCF项目中,必不可少地是传递数据,把客户端需要传递的数据传送到服务中,服务接收到数据再对其进行处理.然而在WCF中,传递的类型必须标记为DataContractAttribute属性

小康陪你学JAVA--------数组的拷贝操作

API提供了很多方法供程序开发员使用,接下来两篇将和大家分享两个常用的数组操作方法,今天来介绍第一种方法——数组的拷贝操作. 范例:TestJava4_4.java 01 // 以下这段程序说明数组的拷贝操作 02 public class TestJava4_4 03 { 04  public static void main(String[] args) 05  { 06       int a1[] = {1,2,3,4,5} ;  //声明两个整型数组a1.a2,并进行静态初始化 07 

跟我一起学WCF(11)——WCF中队列服务详解

一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端和服务之间的离线工作,客户端将消息发送到一个队列中,再由服务对它们进行处理.下面让我们具体看看WCF中的队列服务. 二.WCF队列服务的优势 在介绍WCF队列服务之前,首先需要了解微软消息队列(MSMQ).MSMQ是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布在同一台机器

WCF 服务器调用回调函数 单程-双程操作模式:

服务器端Server 实现回调接口Interface定义.客户端实现回调接口Interface实现,从而实现服务器端通过 var channel = OperationContent.Current.GetCallbackChannel</*接口类名*/>(); 获取回调实例对象channel; 通过channel可以在服务器端调用客户端的实现相关回调接口. 在分布式服务器中 实现心跳包的方式绝大部分使用了这种方法. 可轻松 使用 基于双程模式 + delegate 实现 事件驱动型集群分布式

跟我一起学WCF(10)——WCF中事务处理

一.引言 好久没更新,总感觉自己欠了什么一样的,所以今天迫不及待地来更新了,因为后面还有好几个系列准备些,还有很多东西需要学习总结的.今天就来介绍下WCF对事务的支持. 二.WCF事务详解 2.1 事务概念与属性 首先,大家在学习数据库的时候就已经接触到事务这个概念了.所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单元.例如,银行转账功能,这个功能涉及两个逻辑操作 从一个账户A中扣钱 另一个账户B增加对应的钱. 现实生活中,这两个操作需要要么都执行,要么都不