zoukankan      html  css  js  c++  java
  • 利用Vista新技术WCF开发构建服务系统

     

    摘 要 WCFWindows Communication Foundation)是微软基于SOAService Oriented Architecture)推出的.Net平台下的框架产品,它代表了软件架构设计与开发的一种发展方向。本文通过一个详细的例子介绍WCF开发构建服务的实现过程,可以预言该技术将在分布式系统中得到广泛的应用。

    关键字 .Net 3.0C#WCFSOAService


    一、前言

    WCF(以前为 Indigo),是Vista的一项新技术,也是Vista的一项核心技术。它扩展了 .NET Framework 2.0 的功能,为开发人员提供了构建安全、可靠的可互操作应用程序的高效框架。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案,且能与已有系统兼容协作。WCF是微软分布式应用程序开发的集大成者,它整合了.Net平台下所有的和分布式系统有关的技术,例如ASP.NET Web服务(ASMX)、增强Web服务扩展(WSE)、.Net Remoting、企业服务(Enterprise Service)和微软消息队列(MSMQ)。以通信范围而论,它可以跨进程、跨机器、跨子网、企业网乃至于Internet;以宿主程序而论,可以以ASP.NETEXEWPFWindows FormsNT ServiceCOM+作为宿主(Host)WCF可以支持的协议包括TCPHTTP,跨进程以及自定义,安全模式则包括SAMLKerberosX509,用户/密码,自定义等多种标准与模式。

    WCF是一种基于服务的编程模型,而这种服务模型的设计目的初衷在于降低分布式应用程序开发的难度,提供高可靠性、高质量的服务。了解WCF开发构建服务对在Windows平台下开发分布式系统非常重要。

    二、为什么需要WCF

    当前在.Net平台下的分布式系统技术中最主要的是ASMXWSE.Net Remoting、企业服务以及MSMQ。那么,这些技术是否存在着什么重大缺陷从而使得微软在新平台下把它们统统换掉呢?答案是没有,惟一的问题就是这些技术太多。

    使用ASMXWSE,可以借助支持跨平台协同操作的Web服务和Web服务客户程序;.Net Remoting是通用语言运行时环境(CLR)集成机制,用于跨应用域边界与对象进行通信,可以提供非常灵活的扩展模型;企业服务提供了在分布式环境下执行相关工作的多方集成事务的功能,拥有丰富的安全模型,而且是建立在成熟、平台集成、安全和快速的传输机制上;利用MSMQ可以获得可扩展、耐用、灵活的队列消息,负责把数据从一个地方可靠地传送到另一个地方。

    每一种技术都有它的好处,惟一的问题是你往往要为到底该使用其中的哪项根本性技术进行选择。如果你需要企业服务的任何特性,并且决定使用它,那么你的实现策略会与你使用ASMX时大不相同。如果你需要非常可靠的消息传送功能,并决定通过MSMQ发送消息,而不是通过普通HTTP发送消息,那么你的代码会与通过面向方法的代理调用截然不同,除非你自己添加了一些衔接代码(plumbing code),或者使用企业服务的队列组件(Queued Components)特性。

    WCF具有统一性、互操作性、安全与可信赖性以及兼容性等优势。WCF完全可以看作是ASMXWSE.Net Remoting、企业服务和MSMQ等技术的并集,它整合了这五种技术的丰富特性。利用WCF,就可以解决包括安全、可信赖、互操作、跨平台通信等需求。

    三、WCF的技术要素

    大多数WCF功能被包括在位于System.ServiceModel命名空间的单个的程序集System.ServiceModel.dll中。一个WCF Service由下面三部分构成:
      1Service Class:一个标记了[ServiceContract]属性的类,在其中包含了多个方法。除了标记了一些WCF特有的属性外,这个类与一般的类没有什么区别。

    2Host(宿主):可以是IIS,应用程序,进程如Windows Service等,它是WCF服务运行的环境。

    3Endpoints:可以是一个,也可以是一组,它是WCF实现通信的核心要素。

    WCF服务由一个Endpoints集合组成,每个Endpoint就是用于通信的入口,客户端和服务端通过Endpoint交换信息,一个Endpoint由三部分组成:AddressBindingContract。便于记忆习惯简称为ABCs

    AddressEndpoint的网络地址,它标记了消息发送的目的地。Binding描述的是如何发送消息,例如消息发送的传输协议(如TCPHTTP),安全(如SSLSOAP消息安全)。Contract则描述的是消息所包含的内容,以及消息的组织和操作方式,例如是one-wayduplexrequest/reply。所以Endpoint中的ABCs分别代表的含义就是:wherehowwhat。当WCF发送消息时,通过address知道消息发送的地址,通过binding知道怎样来发送它,通过contract则知道发送的消息是什么。

    四、程序实现

    1、开发环境

    WCF可以在XP SP22003 SP1Vista环境下开发,本文是在Windows 2003 SP2系统平台下,系统已经安装有VS.Net 2005 Team Suite。配置步骤如下:

    1) 安装.NET 3.0 Framework。它包括Microsoft® .NET Framework 版本 3.0 可再发行组件包安装公共语言运行库以及运行针对目标 .NET Framework 3.0 开发的应用程序所需的关联文件。

    2) 安装Windows SDKWindows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components。虽然是for Vista的,但是在2003或者XP下开发也需要安装。SDK 提供了需要开发运行在window上应用程序的库文件、头文件、文档、示例和工具。

    3)安装Visual Studio 2005 Extensions for WCF, WPFVS2005开发WCFWPF的集成插件。

    以上的下载地址都可以在http://msdn2.microsoft.com/en-us/windowsvista/aa904955.aspx找到。注意安装的先后顺序。通过以上3步,就可以用vs2005开发基于.Net Framework 3.0WCF应用了。

    2、程序框架

    VS.Net2005中建立名为Dean.WCFService的解决方案。整个程序框架如图1所示,由四个项目组成,分别是ContractServiceHostingClient。各个项目的项目类型和功能作用如表 1所示。

    1 程序框架

     

    1项目类型和功能作用

     项目

    类型

    作用

    Contract

    Class Library Project

    定义服务契约和数据契约

    Service

    Class Library Project

    Service的业务逻辑

    Hosting

    ASP.NET Web Application

    服务宿主在IIS

    Client

    Windows Application

    客户端调用服务

    问题的提出:本实例是模拟电子银行存取款功能。系统提供查询账号余额和存取款功能服务供其它业务系统使用,其它业务系统有ATM机、柜台业务处理系统以及其它交易接口等。例子中的客户端程序就是模拟了ATM机。这是一个典型的分布式应用系统。

    3、服务契约

    WCF中,所有的服务都暴露契约。契约是一种描述服务所实现功能的平台中立的标准的方式。WCF定义了四种类型的契约:服务契约,描述可以在服务上执行哪些操作;数据契约,定义传入和传出服务的数据类型;消息契约,允许服务直接与消息进行交互;错误契约,定义哪些错误将被该服务所激发,以及该服务怎样处理错误信息和把如何把它们传播到客户端。在项目Dean.WCFService.Contract中用到了服务契约和数据契约,项目需引用System.ServiceModel DLL

    服务契约的定义通常采用接口的方式,在接口前面加入ServiceContract属性来表明该接口定义的是一个服务契约。同样通过这种声明式的编程模式在方法名前增加属性OperationContract定义为契约的一个操作方法。其它和一般的接口没有什么区别。

    数据契约的定义是在一般的类前面加属性DataContract,并在数据成员前面加DataMember属性。具体代码如下:

    namespace Dean.WCFService.Contract

    {

     [ServiceContract()]//服务契约

     public interface IAccountService

     {

     [OperationContract]//服务契约的操作方法

     bool DepositByAccountNo(string AccountNo,decimal ammount);

     [OperationContract]

     bool WithdrawByAccountNo(string AccountNo,decimal ammount);

     [OperationContract]

     decimal QueryByAccountNo(dcCustomerInfo dataContractValue);

    }

    [DataContract]//数据契约

    public class dcCustomerInfo

    {

     string accountNo;

     string cardNo;

     [DataMember]

     public string AccountNo

     {

     get { return accountNo; }

     set { accountNo = value; }

     }

     [DataMember]

     public string CardNo

     {

     get { return cardNo; }

     set { cardNo = value; }

     }

    }

    }

    4、业务逻辑

    前面创建了Dean.WCFService.Contract,定义了服务契约。即描述服务所提供的功能。但是没有具体的实现过程。这些操作方法的实际业务逻辑是什么,通过Dean.WCFService.Service来具体实现。其实和普通的接口实现是一样的。在例子中,为了便于演示,直接定义了静态常量balance代表账户余额。项目需引用Contract项目,实施服务契约的代码如下:

    namespace Dean.WCFService.Service

    {

       //实施服务契约,即实现接口的方法

       public class AccountService : IAccountService

       {

         static decimal balance = 5000;

         //根据账号和金额存款

         public bool DepositByAccountNo(string AccountNo,decimal ammount)

          {

          //本例子是直接指定账户的金额。实际运用中,这些数据都是存在数据库中

          //判断账户是否存在,如果不存在返回false

          balance = balance + ammount;

          return true;   

           }

          //根据账号和金额取款

          public bool WithdrawByAccountNo(string AccountNo,decimal ammount)

           {

            if (ammount > balance)

             { return false; }

             else {

               balance = balance - ammount;

               return true;

               }

            }

          //根据数据契约查询账号余额

    public decimal QueryByAccountNo(dcCustomerInfo dataContractValue)

          {

           string accountno=dataContractValue.AccountNo;

           //判断账户存不存在,如果不存在,返回为-1

             return balance ;

            }

       

    }

    5IIS宿主

    WCF服务必须宿主到某一个运行的进程中,Dean.WCFService.Hosting项目的实质就是把服务置于IIS的进程中,以Endpoint的形式暴露出来,并开始监听来自Client端的请求。项目需引用Service项目。采用IIS宿主主要优点是,在发生客户端请求时宿主进程会被自动启动,并且可以依靠IIS来管理宿主进程的生命周期。

    Hosting项目中新增一个文本文件,修改文件名为AccountService.svc,内容改为:

    <%@ServiceHost Language="C#" Service ="Dean.WCFService.Service.AccountService" %>

    选中Web.config文件,点击鼠标右键选择[Edit WCF Configuration…]打开WCF服务配置软件,建立服务通信端。主要配置服务、契约、通信方式、服务行为和地址等。修改后的配置文件serviceModel节为:

    <system.serviceModel>

     <behaviors>

     <serviceBehaviors>

       <behavior name="BankServiceBehavior">

        <serviceMetadata httpGetEnabled="true" />

       </behavior>

     </serviceBehaviors>

     </behaviors>

     <services>

     <service behaviorConfiguration="BankServiceBehavior" name="Dean.WCFService.Service.AccountService">

     <endpoint binding="basicHttpBinding" contract="Dean.WCFService.Contract.IAccountService" />

     </service>

     </services>

    </system.serviceModel>

    调试通过后就可以在IIS中发布。在IE地址栏输入http://localhost:8080/accountservice.svc。如果服务运行正确就会返回相应的说明和用客户端调用服务的方法,如图2所示。

     

    6、客户端调用

    为了调用服务上的操作,客户端首先需要把服务契约导入到客户端的本地描述中。在VS.Net2005中可以直接添加服务引用来完成,添加了服务引用后会在客户端项目里增加两个文件。一个是配置文件,一个是代码文件,如图3。前者是WCF服务的配置信息,主要包含的是EndpointAddressBinding以及Contract的配置。 后者主要包含了一个实现了IAccountService接口的Proxy对象。也可以利用SvcUtil.exe工具来生成类似的两个供客户端程序调用服务所使用的文件。

    如果契约的方法定义发生改变或者新增操作方法,可以通过选中ATMService.map,点击右键选择升级服务引用来更新这两个文件。

    2 IE中测试WCF服务图


    3 客户端引用服务文件结构


    4 客户端程序

      根据图4建立客户端调用WCF服务窗体,并添加控件和设置好属性。分别添加查询余额按钮单击事件button1_Click,存款单击事件button2_Click和取款单击事件button3_Click,主要代码如下:

    private Client.ATMService.AccountServiceClient myService = new Client.ATMService.AccountServiceClient();

    private void button1_Click(object sender, EventArgs e)

     {//查询余额            Client.ATMService.dcCustomerInfo dataContractValue = new Client.ATMService.dcCustomerInfo();

       dataContractValue.AccountNo = textBox1.Text;

       dataContractValue.CardNo = "95550284312547";

       //调用服务操作方法QueryByAccountNo

       decimal balance= myService.QueryByAccountNo(dataContractValue);

       txtboxLog.Text = txtboxLog.Text + "\r\n查询账号" + dataContractValue.AccountNo + "的余额为:" + balance.ToString();

        }

    private void button2_Click(object sender, EventArgs e)

       {//存款

        decimal ammount = Convert.ToDecimal(textBox2.Text);

      string accountno=textBox1.Text;

        if (myService.DepositByAccountNo(accountno, ammount))

         {

          txtboxLog.Text = txtboxLog.Text + "\r\n向账号"+accountno+"存入"+textBox2.Text;

            }

            else

          {

           txtboxLog.Text = txtboxLog.Text + "\r\n向账号"+accountno+"存入失败";

            }

         }

    程序先实例化AccountServiceClient对象。如果需要传入数据契约也需要实例化,例如查询余额时,传入的参数是dcCustomerInfo。再根据实例化的对象调用WCF服务的操作方法。

    五、结束语

    WCF是一种用于构建Windows面向服务的应用程序的SDK。在.Net平台下利用WCF开发基于SOA的分布式系统变得更加容易,微软将所有与此相关的技术要素都包含在内。可以说掌握了WCF,就相当于掌握了叩开SOA大门的钥匙。本文就是通过一个实际例子详细的介绍了这一技术实现过程。

    参考文献

    1MSDN文档

    2Robert Shelton, Jr. Windows Communication Foundation (Workshop)

  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/13590/p/802626.html
Copyright © 2011-2022 走看看