Fork me on GitHub
IIS中部署WCF
  • 环境条件:
    1. WinXP SP2.Cn
    2. Visual Studio Team System 2008 Beta2.En
    3. VPC 2007.En
    4. Win2K3 Server SP2
  • 准备工作:
    1. 在WinXP SP2的机器上安装VS2008;
    2. 在WinXP SP2的机器上安装VPC 2007;
    3. 在VPC 2007中准备两个Win2K3 Server的虚拟环境,并为其安装.NET 3.5 Framework Beta2 RunTime

       

       

       

      虚拟机环境A

      虚拟机环境B

      设备名

      Win2K3-I

      Win2K3-II

      机器名

      Server-01

      Server-02

      内存分配

      256M

      256M

      IP分配

      192.168.4.10

      192.168.4.11

       

  • 基于WCF的面向服务结构Demo概述:
      VS2008已经提供了两类关于WCF的项目模板:Web分类下的WCF Service Application、WCF分类下的WCF Service Library及其工作流相关的WCF Service模板。

     

      WCF Service Appliaction项目模板:该模板将IIS作为WCF Service的宿主,对外提供服务,默认情况下将使用HTTP协议的wsHttpBinding,即WebServices。但在这个项目模板中,不光包含了*.svc类型的服务声明,

      WCF Service Library项目模板:该模板将会默认建立Contract的接口以及Service的实现类。在该类型项目中添加一个WCF Service类型项,会同时添加IService接口和Service的实现类。在IService这个接口文件中会包含两个类:ServiceContract契约接口和DataContract数据契约类;而Service这个类是对IService接口文件中的ServiceContract接口的实现。按照WCF设计的思路可以理解为,在IService这个接口文件中定义的都是服务契约Contract,是需要提供给Service调用者的依据,即服务接口和数据实体,统称契约Contract。
      按照WCF Service Libray模板设计,把服务接口和数据实体都定义在一起,并且在把服务接口的具体实现也包含在了一个程序集中。明显,这不是一种满足低耦合的设计,因此,在这个例子中会把这几部分单独分开建立项目。

      在这个WCF例子中,会把整个架构划分为6个项目,没有明确说明的都是基于.NET 3.5的类库Class Librayr型项目。

    •  
      1. Fetion.Web.Framework.DataContract
        简要说明:数据契约DataContract,它的定义有些类似于传统项目中的业务实体对象BusinessEntity。
        项目引用:System.Runtime.Serialization
      2. Fetion.Web.Framework.ServiceContract
        简要说明:服务契约ServiceContract,服务契约都是接口Interface,用于定义服务的操作接口。
        项目引用:System.ServiceModel
             Fetion.Web.Framework.DataContract
      3. Fetion.Web.Framework.BusinessService
        简要说明:服务实现Service,对服务契约ServiceContract接口的具体实现,包含了Service的实际业务操作。
        项目引用:Fetion.Web.Framework.DataContract
             Fetion.Web.Framework.ServiceContract
      4. Fetion.Web.Framework.ServiceContainer
        简要说明:服务容器,即WCF的宿主。以WCF Service Appliaction项目模板建立项目,在这基础上做修改使成为满足需要的项目。
        项目类型:Web分类下的WCF Service Appliaction
        项目引用:Fetion.Web.Framework.BusinessService
      5. Fetion.Web.Framework.ServiceWrapper
        简要说明:客户端服务代理,该层完成对服务器端Service的封装,包含权限安全性、数据加密压缩、缓存等方面的内容。
        项目引用:System.ServiceModel
             Fetion.Web.Framework.DataContract
             Fetion.Web.Framework.ServiceContract
      6. Fetion.Web.Framework.UIConsole
        简要说明:UI控制台程序,用来代替最终的UI层对WCF Service进行测试.
        项目类型:Windows分类下的Console Appliaction
        项目引用:System.ServiceModel
             Fetion.Web.Framework.DataContract
             Fetion.Web.Framework.ServiceContract
             Fetion.Web.Framework.ServiceWrapper

         

        整个项目结构如下图所示:

 

                             Project

  • Fetion.Web.Framework.DataContract
      Fetion.Web.Framework.DataContract中包含了需要和前台传递的数据实体对象,在这个例子中做了一个叫做HostInfo的类作为数据载体,HostInfo只有两个属性,用于记录主机名和主机IP,便于在后面做负载均衡试验时确定是从哪台服务器上执行的。其中,[DataContract]标记HostInfo类为WCF的数据契约类,这个标记非常类似以前常用的Serializable属性,可以实现对类标记为可序列化;[DataMember]标记需要被暴露为数据契约的数据字段属性。

     

                        Fetion.Web.Framework.DataContract.HostInfo

  • Fetion.Web.Framework.ServiceContract
      
    Fetion.Web.Framework.ServiceContract中包含的都是接口Interface,并将接口用[ServiceContract]标记为WCF的服务契约,用[OperationContract]标记里面的方法为具体的操作契约。在ServiceContract中定义了服务的结构框架,一方面制约服务的具体实现,另一方面可以作为调用Service方的调用凭据。(在MSDN以及多数WCF的资料中会推荐用svcutil.exe来生成服务调用凭据,个人对此并不认同,后面到客户端调用时再详细阐述)

     

           Fetion.Web.Framework.ServiceContract.IServerEnvironment

  • Fetion.Web.Framework.BusinessService
      Fetion.Web.Framework.BusinessService中是对Fetion.Web.Framework.ServiceContract的具体实现。在这个例子中,实现了一个简单的业务逻辑:获取当前服务器的机器名以及IP地址,并填充到DataContract中定义的数据实体中,提供给服务调用方。
      注意:在这个例子屏蔽掉了一个系统应该有的业务领域以及数据访问等,应该由此层完成对业务的最终封装,并发布给调用方使用。

     

                        Fetion.Web.Framework.BusinessService.ServerEnvironment

  • Fetion.Web.Framework.ServiceContainer
      
    Fetion.Web.Framework.ServiceContainer是WCF的宿主容器,将WCF依托在IIS上。WCF和.NET Remoting相同,可以以任何Application做为宿主:Console Appliaction、Windows Service、WinForm、Web Service Applicaton,但为了能够使用IIS提供的安全性和负载均衡特性,这个例子里面选择IIS作为WCF Service的宿主。
      首先,添加一个WCF Service Appliaction类型项目,添加项目引用后,删除默认添加的IService1.cs和Service1.svc.cs文件,然后修改Service1.svc文件名为ServerEnvironmentService.svc,并打开该文件(如果还没有删除Service1.svc.cs,则不能打开该svc文件),修改里面的<%@ ServiceHost%>的Service属性为引用的Service实现类Fetion.Web.Framework.BusinessService.ServerEnvironment,并删除CodeBehind属性。
      因为默认的模板采用的是wsHttpBinding,而wsHttpBinding缺省使用的Security Mode是Message,而在Message模式下Windows集成验证是缺省的Credentials,所以就不再修改Web.Config,使用缺省的安全验证模式。(参见后附的)
      设置该项目为启动项目,在IE中输入http://localhost:3060/ServerEnvironmentService.svc验证服务正常提供。

     

                       ServerEnvironmentService.svc

  • Fetion.Web.Framework.ServiceWrapper
      
    Fetion.Web.Framework.ServiceWrapper是作为WCF Service的调用端。VS2008对于WCF的调用提供了很多种快捷的方式:1、直接在项目上反选Add Service Reference,会以类似于Add Web Reference的方式自动生成对Service的引用代理生成,然后在程序中可以直接调用生成的代理类;2、使用svcutil.exe来生成用于调用服务的代理类和app.config,将文件添加到项目中,就可以通过生成的代理类调用WCF Services。
      无论以上提供的哪一种方法,都会在WCF Services调用端重新生成一个代理类,包含服务接口和数据实体对象类,虽然使用方便,但改变了整个框架的完整性和一致性。事实上重新生成的代理类和实体类都是对Fetion.Web.Framework.ServiceContract和Fetion.Web.Framework.DataContract的重复实现。如果前后台的实体对象不是同一个对象,可能会在开发中产生一些麻烦,导致两个本来一致的实体对象之间需要互相赋值。
      并且,自动生成的代理类完成了对调用的完全封装,如果想再添加关于数据压缩,缓存,加密,权限方面的操作将无法进行。因此,推荐在ServiceWrapper层独立封装操作调用类。
      在Demo中采用扩展方法对所有System.ServiceModel.ClientBase的子类添加了一个方法:Credential(),在这个方法中封装了对WCF Service权限校验认证的代码。并让对应服务的Wrapper类继承和实现了System.ServiceModel.ClientBase和ServiceContract的IServerEnvironment接口。

     

    WrapperRightExtension.cs

                          Fetion.Web.Framework.ServiceWrapper.WrapperCredentialExtension

    ServerEnvironmentServiceWrapper.cs

                     Fetion.Web.Framework.ServiceWrapper.ServerEnvironmentServiceWrapper

  • Fetion.Web.Framework.UIConsole
      Fetion.Web.Framework.UIConsole,作为最终的UI展示,调用ServiceWrapper封装后的方法,实现对WCF Service的远程调用。在它的app.config中写入对WCF Service调用的相关配置信息,如Binding,Service的URI,服务接口类等。

     

                         app.config


      以上,完成了WCF Service项目的Demo,接下来需要把项目部署到Win2K3环境中,并为两台虚拟机环境建立起负载均衡群集,实现WCF Service部署在NLB环境中。

  • 发布WCF Service到Win2K3 Server

     

      为了方便,决定采用VS2008提供的Publish功能,要使用这个功能需要Win2K3 Server的IIS上安装了FrontPage扩展。
      在Fetion.Web.Framework.ServiceContainer项目上反选Publish,在Target location项的详细中选择Remote Site,输入:http://192.168.4.10/FetionFramework,如果是第一次发布,还需要点击New Web Site后确定。在点击publish按钮后,如果正常应该已经在Server-01完成了WCF Service的部署。通过在IE中输入http://192.168.4.10/FetionFramework/ServerEnvironmentService.svc验证是否正确部署。(注意,需要检查默认站点上使用的.NET Framework版本,需要设置为.NET Framework 2.0)。
      重复上述过程,完成对Server-02的部署。

     

  • 使用控制台对访问验证部署

     

      使用Fetion.Web.Framework.UIConsole控制台对Server-01和Server-02访问验证,需要分别在Server-01和Server-02上建立两个Windows帐号:IISAdmin,密码:8848,默认的Users组即可。修改UIConsole的app.config中的address属性为http://192.168.4.10/FetionFramework/ServerEnvironmentService.svc,以验证Server-01的访问正常
      重复以上过程,完成对Server-02的验证。

     

  • Server-01和Server-02的负载均衡NLB环境搭建

     

      查看Server-01的网卡属性,选中:网络负载均衡后,点击属性进行配置。首先在群集IP设置中填写IP地址为192.168.4.100,子网掩码为255.255.255.0,群集操作模式选择多播;然后在主机参数中的专用IP配置设置为192.168.4.10(即本机IP);最后在端口规则中将端口范围改为80~8080。完成对网络负载均衡的属性设置后,点击Internet协议(TCP/IP)的属性进行设置:在高级中添加IP地址192.168.4.100,掩码255.255.255.0。完成后确定,等待系统进行配置。

      完成对Server-01的配置之后,再对Server-02进行同样的配置,只是在设置主机参数中的专用IP配置时,需要设置为Server-02自己的IP地址,即192.168.4.11。这样就完成了对NLB负载均衡环境的最简化搭建。

     

  • 使用UIConsole控制台验证NLB环境搭建成功

     

      修改UIConsole程序的app.config中的address属性为http://192.168.4.100/FetionFramework/ServerEnvironmentService.svc,运行该控制台程序,应该可以得到其中一台Win2K3 Server的机器名和IP地址,此时,关闭该Server后,再次执行该控制台程序,如果依然能正常访问,并且得到另一台服务器的机器名和IP地址,则验证整个试验成功。

1. 安装完 VS Extension 后,我们可以创建一个 WCF service 的网站项目。
2. 添加一个 WCF service 新项,系统自动会创建 Service.svc、App_Code\Service.cs 等必要文件。
3. 在 Service.cs 文件中完成服务编码。
4. 添加 web.config 文件,并在其位置单击鼠标右键,打开 "Microsoft Service Configuration Editor" 工具完成服务配置。
5. 注意添加 serviceMetadata,否则我们使用浏览器无法查看,也无法创建客户端代理。

 

web.config 演示 (注意配置文件中并没有提供服务地址)

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  
<system.serviceModel>
    
<services>
      
<service behaviorConfiguration="MyServiceTypeBehaviors" name="MyService">
        
<endpoint binding="wsHttpBinding" contract="IMyService"/>
      
</service>
    
</services>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="MyServiceTypeBehaviors">
          
<serviceMetadata httpGetEnabled="true"/>
          
<serviceDebug includeExceptionDetailInFaults="true"/>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
  
<system.web>
    
<compilation debug="true">
  
</system.web>
</configuration>

service.svc

<%@ ServiceHost Language="C#" Debug="true" Service="MyService" CodeBehind="~/App_Code/service.cs" %>

建议将服务放到一个单独的 Library 中,这样更改宿主环境会更方便一点,不过上述步骤要做些修改。
1. 安装完 VS Extension 后,我们可以创建一个 WCF service 的网站项目。
2. 添加服务所在类库的引用。
3. 创建 svc 文件,内容也所不同。如 <%@ ServiceHost Debug="true" Service="Learn.Library.WCF.CalculateService" %>,注意使用包含名字空间的全名。
4. 添加 web.config 文件,打开 "Microsoft Service Configuration Editor" 工具完成服务配置。
5. 注意添加 serviceMetadata,否则我们使用浏览器无法查看,也无法创建客户端代理。
web.config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  
<system.serviceModel>
    
<services>
      
<service behaviorConfiguration="MyServiceTypeBehaviors" name="Learn.Library.WCF.CalculateService">
        
<endpoint binding="wsHttpBinding" contract="Learn.Library.WCF.ICalculate"/>
      
</service>
    
</services>
    
<behaviors>
      
<serviceBehaviors>
        
<behavior name="MyServiceTypeBehaviors">
          
<serviceMetadata httpGetEnabled="true"/>
          
<serviceDebug includeExceptionDetailInFaults="true"/>
        
</behavior>
      
</serviceBehaviors>
    
</behaviors>
  
</system.serviceModel>
  
<system.web>
    
<compilation debug="true">
  
</system.web>
</configuration>
posted on 2010-08-03 15:14  HackerVirus  阅读(1627)  评论(0编辑  收藏  举报