zoukankan      html  css  js  c++  java
  • WCF分布式开发步步为赢(1):WCF分布式框架基础概念

    众所周知,系统间的低耦合一直是大型企业应用系统集成追寻的目标,SOA面向服务架构的出现为我们的如何利用现有企业系统资源进行企业ERP系统设计和实现提供了重要的参考原则。SOA如此炙手可热,各大厂商都推出了自己的中间件产品,比如Oracle Fusion和 SAP NetWeaver,IBM、BEA等企业也推出了自己基于SOA的解决方案。基于J2EE平台的SOA架构设计中的一个重要概念就是EJB企业服务总线,作用是实现各个系统的数据交互。而.NET平台上,WCF就是微软为各个系统的数据交互提供通讯基础框架。由于论文课题的原因,我对产生了SOA(Service-oriented architecture,面向服务架构)有了接触,并且产生了浓厚的兴趣。故此对.NET平台上基于SOA的企业应用系统集成和实现技术进行潜心学习,总结心得和体会,整理出布式开发的系列文章,与大家分享。   

         下面介绍一下《WCF分布式开发步步为赢》系列文章的结构。首先会是WCF分布式开发基础概念的介绍,其次会设计各个知识点详细的介绍和应用,中间会穿插与以前技术的对比分析,涉及服务契约、数据契约、操作契约、事物、安全、消息队列等重要概念。同样作为老徐一贯的风格,我会尽量做到文章的调理清晰、系统详细、通俗易懂!也会放出标注的详细代码供大家参考学习。    本节文章的结构是:1.WCF基础概念介绍2.WCF新的特性3.WCF框架模型4.实现代码分析5.总结。

    【1】WCF基础概念介绍

         要学习WCF,首先我们要清楚WCF的基本概念,那么什么是WCF呢?

         WCF全称Windows Communication Foundation,是Microsoft为构建面向服务的应用提供的分布式通信编程框架,是.NET Framework 3.5的重要组成部分。使用该框架,开发人员可以构建跨平台、安全、可靠和支持事务处理的企业级互联应用解决方案。
      根据微软官方的解释,WCF(之前的版本名为“Indigo”)是使用托管代码建立和运行面向服务(Service Oriented)应用程序的统一框架。它使得开发者能够建立一个跨平台的安全、可信赖、事务性的解决方案,且能与已有系统兼容协作。WCF是微软分布式应用程序开发的集大成者,它整合了.Net平台下所有的和分布式系统有关的技术,如Enterprise Sevices(COM+).Net Remoting、Web Service(ASMX)、WSE3.0和MSMQ消息队列。以通信(Communiation)范围而论,它可以跨进程、跨机器、跨子网、企业网乃至于 Internet;以宿主程序而论,可以以ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host)。WCF可以支持的协议包括TCP,HTTP,跨进程以及自定义,安全模式则包括SAML, Kerberos,X509,用户/密码,自定义等多种标准与模式。也就是说,在WCF框架下,开发基于SOA的分布式系统变得容易了,微软将所有与此相关的技术要素都包含在内,掌握了WCF,就相当于掌握了叩开SOA大门的钥匙。(参考MSDN)

        这里SOA概念我们要明确一下,SOA(Service-oriented architecture,面向服务架构)是一种架构模式和设计原则。在<Programming WCF Services >By Juval Lowy 一书中解释为SOA(Service-oriented applicatoin)面向服务的应用程序,两者应该不冲突,后者应该是采用SOA面向服务架构设计和实现的应用程序(Service-oriented applicatoin)。

       WCF的强大之处就是因为整合了.Net平台下所有的和分布式系统有关的Enterprise Sevices(COM+).Net Remoting、Web Service(ASMX)、WSE3.0和MSMQ消息队列等技术,我在之前的WCF分布式开发必备知识(4)WSE3.0构建Web服务安全(4)系列文章中都给出了详细的介绍,这里就不在详述,有兴趣的朋友可以自己查阅。以后具体介绍WCF相关知识点的时候需要的地方我会在进行讲解。

    【2】WCF新的特性

       Indigo 有三项突出的特性:与多种现有 Microsoft 技术的统一性,对跨供应商互操作性的支持,以及显式的面向服务特性。

     【2.1】 Microsoft 分布式计算技术的统一性

       Microsoft以前的分布式计算技术特性和应用领域不同。要构建基本的可互操作的 Web 服务,最佳选择是 ASP.NET Web 服务(ASMX)。要连接两个基于 .NET Framework 的应用程序,选择 .NET Remoting。如果应用程序需要分布式事务和其他更高级的服务,其创建者一般会使用企业服务Enterprise Sevices,即COM+ 的继任者。要构建Web 服务安全,使用WS-Addressing 和 WS-Security规范,开发人员可以构建采用 WSE3.0的应用程序。而要创建基于消息的排队式应用程序,基于 Windows 的开发人员则应使用 Microsoft 消息队列 (MSMQ)。 各个技术的具体特性和WCF对比如下表:

     

    ASMX

    .NET Remoting

    企业服务

    WSE

    MSMQ

    Indigo

    Web 服务

    X

           

    X

    .NET - .NET 通信

     

    X

         

    X

    分布式事务等。

       

    X

       

    X

    WS-* 规范支持

         

    X

     

    X

    队列消息传输

           

    X

    X

         WCF支持了以前分布式技术的所有的特性,因而对于建立分数是应用更加的灵活和全面。

    【2.2】与非 Microsoft 应用程序的互操作性

         由于 Indigo 的基本通信机制是 SOAP,因此 Indigo 应用程序可与大量运行于各种上下文环境的其他软件进行通信。基于 Indigo 构建的应用程序可与下列所有程序进行交互:

    1)运行于同一 Windows 计算机上不同进程中的 Indigo 应用程序。

    2)运行于另一 Windows 计算机上的 Indigo 应用程序。

    3)基于其他技术构建的应用程序,如基于 Java 2 企业版 (J2EE) 构建的、支持标准 Web 服务的应用程序服务器。

    4)Indigo 应用程序还可以与基于 Indigo 以前的 .NET Web 服务(ASMX)构建的应用程序进行互操作。

     

        这样通过标准的SOAP消息WCF可以与其他应用程序进行交互,很好地支持了跨平台跨操作系统的的目标。当然WCF中支持安全、事物、MTOM特性,这些都以前WSE中的主要概念,我们发现WCF中也进行了扩展和支持。利于技术的向前兼容。 

    【2.3】对面向服务开发的显式支持

         面向服务是一个广泛的领域,它包含面向服务应用程序和更广泛的面向服务体系结构 (SOA) 的概念。在设计此项技术的过程中始终遵守四项基本原则:

         1.共享架构,而不是类:与旧的分布式对象技术不同,服务仅通过精心定义的 XML 接口与其客户端进行交互。跨越服务边界传递完整的类、方法及全部之类的行为被禁止。

         2.服务具有自主性:服务及其客户端同意它们之间的接口,但相互独立。它们可以采用不同的语言编写,可以使用不同的运行时环境(如 CLR 和 Java 虚拟机),可以运行在不同操作系统上,还可以存在其他方面的不同。

         3.边界是显式的:分布式对象技术 [如分布式 COM (DCOM)] 的目标之一是使远程对象尽可能看上去像本地对象一样。虽然这种方法通过提供一种通用编程模型在某些方面简化了开发,但也同时隐藏了本地对象与远程对象之间不可避免的区别。服务通过使服务与其客户端之间的交互更明显而避免了这一问题。隐藏分布式特性并非目的。

         4.采用基于策略的兼容性:决定在系统之间使用哪些选项应取决于基于 WS-Policy 的机制。

          WS-Policy 在WSE3.0里我们应该比较常见,通过策略配置来支持和实现Web服务的安全。这里很多技术概念我们都可以从早期的分布式技术里找到原型。

    【3】WCF服务框架模型

        下面我们来介绍一下WCF服务的基本结构。     WCF服务的基本结构如下图所示:

    每个 Indigo 服务均由三个部分构成: 

        1.服务类:采用 C# 或 VB.NET 或其他基于 CLR 的语言编写,实现一个或多个方法。通常包括服务契约、操作契约和数据契约。 
         2.宿主:一种应用程序域和进程,服务将在该环境中运行。ASP.NET,EXE,WPF,Windows Forms,NT Service,COM+作为宿主(Host) 。
         3.终结点:服务暴露出来的地址,由客户端用于访问服务。通常提及的概念就是ABC,即地址、绑定和契约的第一个字母的简称。 如图:

       

    终结点中重要的概念就是绑定,它是实现通信的关键部分。这里定义消息通讯的协议包括HTTP、TCP、UDP、MSMQ等,用户可以根据自己的需要定义。

    【4】实现代码分析

          上面介绍了WCF相关的一些基本概念、特性和框架模型,现在我们来具体实现一个WCF的应用实例。客户端和WCF服务通信的过程如图:

        客户端通过代理调用WCF服务,代理通过服务地址找到特定的服务,调用执行特定的服务方法。

        我们代码的演示部分也分为3个部分,首先是服务类(契约部分),其次是宿主(自己定义一个控制台程序),客户端(控制台)。

    【4.1】契约(Contract)

    定义实现的代码包括服务契约IWCFService、操作契约OperationContract、和数据契约DataContract。具体代码实现如下:

    复制代码

    //ServiceContract 属性以及 Indigo 使用的所有其他属性均在 System.ServiceModel 命名空间中定义,
    //因此本例开头使用 using 语句来引用该命名空间。
    namespace WCFService
    {
        //1.服务契约
        [ServiceContract(Namespace = "http://www.cnblogs.com/frank_xl/")]
        public interface IWCFService
        {
            //操作契约
            [OperationContract]
            string SayHello(string name);
            //操作契约
            [OperationContract]
            string SayHelloToUser(User user);

        }
        //2.服务类,集成接口。实现契约
        public class WCFService : IWCFService
        {
            //实现接口定义的方法
            public string SayHello(string name)
            {
                Console.WriteLine("Hello! {0},Using string ", name);
                return "Hello! " + name;
            }
            //实现接口定义的方法
            public string SayHelloToUser(User user)
            {
                Console.WriteLine("Hello! {0}    {1},Using DataContract ", user.FirstName, user.LastName);
                return "Hello! " + user.FirstName + " " + user.LastName;
            }
        }
        //3.数据契约//序列化为XML,作为元数据封装到服务里
        [DataContract]
        public struct User
        {
            [DataMember]
            public string FirstName;
            [DataMember]
            public string LastName;
        }

    }
    复制代码

    【4.2】宿主(托管进程)

         WCFHost宿主进程托管服务WCFService,项目类型也为控制台应用程序(你也可以创建其他的项目类型)。这里要添加对WCFService类库的引用。托管采用反射方式动态创建服务的实例。具体代码如下:

    复制代码

    //采用自托管方式,也可以是IIS、WAS,Windows服务等用户自定义程序托管服务
       public class WCFHost
        {
            static void Main(string[] args)
            {

                //反射方式创建服务实例,
                //Using方式生命实例,可以在对象生命周期结束时候,释放非托管资源
                using (ServiceHost host = new ServiceHost(typeof(WCFService.WCFService)))
                {
                    //相同的服务注册多个基地址
                    //添加服务和URI,用户资源标识符
                    //Uri tcpAddress = new Uri("http://localhost:8001/WCFService");
                    Uri httpAddress = new Uri("http://localhost:8002/WCFService");
                    //Uri httpAddressLisening = new Uri("http://localhost:8002/WCFService");
                    //host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(), tcpAddress);
                    host.AddServiceEndpoint(typeof(WCFService.IWCFService), new WSHttpBinding(), httpAddress);
                    //判断是否以及打开连接,如果尚未打开,就打开侦听端口
                    //if (host.State !=CommunicationState.Opening)
                    host.Open();
                    //显示运行状态
                    Console.WriteLine("Host is runing! and state is {0}",host.State);
                    //等待输入即停止服务
                    Console.Read();
                }
            }
        }
    复制代码

         这里值得注意的就是绑定协议要和配置文件里的设置一样,不然会出现编译错误或者运行时异常。编译结束会生成可执行文件EXE。

    【4.3】客户端

         客户端要添加对以上服务的引用,如果你初次建立服务,配置不当很容易出现引用服务失败的问题,配置服务相关的错误和解决办法我也整理到WCF分布式开发常见错误解决里了,大家需要的话可以参考,是在遇到苦难可以留言给我一起交流。

       客户端的具体实现代码如下:

    复制代码

    class WCFClient
        {
            static void Main(string[] args)
            {
                
                //IWCFService proxy = ChannelFactory<IWCFService>.CreateChannel(new WSHttpBinding(),
                //////new EndpointAddress("net.tcp://localhost:8001/WCFService"));
                ////new EndpointAddress("http://localhost:8002/WCFService"));

                WCFServiceClient wcfServiceProxy = new WCFServiceClient("WSHttpBinding_IWCFService1");

                
                //通过代理调用SayHello服务
                Console.WriteLine(wcfServiceProxy.SayHello("Frank Xu Lei"));
                ////通过代理调用调用SayHelloToUser,传递对象
                User user = new User();
                user.FirstName = "Lei";
                user.LastName = "Frank";
                Console.WriteLine(wcfServiceProxy.SayHelloToUser(user));
                Console.Read();
            }
        }
    复制代码

         这里可以通过两种方式调用WCF服务,一种是自己编码实现客户端服务代理,要正确添加服务的地址。第二种是当客户端添加服务成功以后,VS2008集成开发工具会在客户端自动生成服务端的操作契约、服务契约等信息,当然包含客户端服务代理类,这个比较关键。具体方法就是在客户端项目右键添加服务应用。输入服务侦听的地址。查找到服务后添加引用会生成一系列服务引用的文件,如图:

    【4.4】运行结果:

        首先要启动服务宿主进程WCFhost.如图:

       

       其次运行客户端,结果如图所示:

    【5】总结

       结果显示调用成功,包括直接调用简单的SayHello方法和通过数据契约调用SayHellotoUser方法。

        此系列文章的取名《WCF分布式开发步步为赢》。在此之前,我曾经整理出WCF分布式开发必备知识(4)WSE3.0构建Web服务安全(4)系列文章,主要系统介绍了微软分布式开发的相关的技术:COM+(Enterprise Services)、.Net Remoting、MSMQ消息队列、Web 服务、WSE3.0等相关知识。目的也就是为了学习WCF打下坚实的基础。步步为营,步步为赢!这个也是本系列文章取名的真正目的原因!    如果你是.NET开发的程序员,老徐的建议是,有时间的话,看看微软早期的分布式开发:COM+(Enterprise Services)、.Net Remoting、MSMQ消息队列、Web 服务、WSE3.0等相关技术。这些技术看是陈旧,实际目前还是应用广泛。而你想要真正成为一个企业应用系统集成领域的专家,这些技术必不可少。

       最后给出本节文章的示例代码,供大家参考。下载连接:/Files/frank_xl/WCFServiceFrankXuLei.rar。希望能对大家有所帮助,也欢迎留言交流~如果感觉不错,希望大家支持和继续关注《WCF分布式开发步步为赢》的后续文章,谢谢~

  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/GoogleGetZ/p/5752517.html
Copyright © 2011-2022 走看看