第二章 寄宿WCF服务

📅 2026/7/5 3:51:50
第二章 寄宿WCF服务
WCF服务的工作原理从功能方面讲WCF服务不外乎是一个对外公布了可供客户端调用的一系列操作的对象。当创建一个服务时通过使用服务契约来描述该服务的操作并创建一个类来实现该服务契约。为了运行服务必须为服务对象提供一个运行时环境该环境使服务能被客户端程序访问。寄宿服务的宿主程序提供运行时环境。从第一章我们可以得知IIS能够提供这样的运行时环境。当然你可以自行创建其他种类宿主程序只要该程序能执行下列任务启动和停止WCF服务侦听客户端的请求并且引导这些请求到服务服务端向客户端返回响应为了理解宿主程序是如何工作的我们先来了解服务端点及WCF运行时如何使用服务端点的绑定元素。下图展示了一个端点典型构成端点地址A绑定B契约(C)。1端点。一个应用程序对外提供一个或者多个端点以供外部应用程序访问。WCF服务的端点包含三个元素地址Address服务的地址受多个因素影响包括它所使用的传输协议因为不同的传输协议使用不同形式的地址空间。绑定Binding绑定用以描述客户端如何连接到服务端及服务端所需的数据的格式。绑定包含下列信息传输协议传输协议必须与服务的地址保持一致。如果你用是IIS来寄宿服务那么你就应该执行使用http或者https传输协议此外WCF还支持TCP协议命名管道消息队列协议。在本章后后续内容中你将会看到这些协议的具体使用。消息的编码方式在大多数情况下请求和返回消息将以XML格式普通文本编码格式进行传输。但是在某些情况下你可能需要先将数据进行二进制编码然后再传输。这种情况适合于传输图像和处理流。在第13章你将会了解到编码消息的详细内容。服务的安全性你可以在消息层和传输层上实现安全性方面的需求虽然各种的协议都有其自身限制和其他特别的要求。在第四章和第五章你将了解到安全方面的具体内容。服务的事务性服务端允许客户端访问一个或者多个资源。客户端程序通过向服务端发送请求然后更新资源。如果一个客户端一次发送多个更新请求其结果将会导致服务端资源的多次更新那么保证所有的更新都可以顺利完成就非常显得重要。如果发生意外服务端应该自动回滚这些操作。这就是事务的定义。在第九章你可以了解到事务的详细信息。服务通信的可靠性客户端通常通过多个网络连接到到服务。但是网络优势并不可靠而且随时可能会失败此时保证客户端与服务端可靠得进行对话就显得非常重要。比如服务端能接受到客户端发送的所有消息并确保这些信息是按照客户端发送的顺序依次到达服务端。 服务端通过实施可靠的消息协议以保证会话的一致性。在第10章你将会了解到可靠性的相关知识。契约ContractWCF服务契约是存储在.NET Framework组件中的一个接口并且用ServcieContract特性标识。服务契约描述了该服务所有的操作这些操作通过OperationContract特性标识。任何操作的输入和输出数据都必须进行序列化。服务契约还规定了数据契约数据契约用来描述复杂数据及如何序列化这些复杂数据。服务对外公布服务契约的描述信息以使客户端程序能准确地调用相应的操作以及使用正确的消息格式想服务端发送请求消息。2处理客户端请求一个服务能同时响应多个客户端的请求。为了达到这个目的宿主程序需处理多个客户端的请求并将服务端的响应返回到对应的客户端。此外宿主程序必须确保服务端和客户端之间的消息应满足其绑定所定义的安全性、可靠性和事务性方面的需求。幸运的是你不必自己亲自写这些代码因为WCF运行时环境为客户端和服务端提供一系列的通道对象用以实现上述需求。通道根据服务端配置文件中的绑定信息执行消息处理流程中的对应任务比如传输通道通过指定的传输协议进行通信事务通道确保会话的一致性。WCF为每个传输协议都内建了相应的通道。WCF还为每种类型的通道提供了不同的数据编码安全管理可靠性和事务性支持。WCF运行时将这些通道组合成一个通道堆栈。所有服务端和客户端的消息都进入该堆栈中对应的通道。该堆栈中每一个通道以某种方式传输消息当完成一个消息传送并将结果输出后下一个消息进入该通道。通道堆栈双向运行从接客户端接受到的消息经过该栈后传送至服务端从服务端的返回消息经过该堆栈后通过网络回传给客户端。如果通道堆栈不能处理消息它将产生一个错误并将给错误消息返回至客户端客户端的消息将不再继续处理。当你启动服务时WCF运行时读取服务配置文件中的端点信息并为配置文件中的每个地址创建一个侦听器。当请求达到该侦听器后WCF运行时根据配置文件中的某个具体地址对于的绑定信息创建一个通道堆栈然后引导来自客户端的数据通过该堆栈。如果一个消息通过堆栈中所有的通道该请求将被传送给一个实例化的服务对象进行处理。前面已经提到WCF服务能同时处理来自多个客户端应用程序的请求。为了完成这个目标WCF运行时创建多个同时存在的服务实例。 WCF运行时创建InstanceContext对象用以控制通道堆栈和服务实例之间的互操作。你可以通过InstatnceContext对象来修改服务实现类的ServcieBehavior特性以修改WCF运行时创建服务实例的方式。ServieBehavior特性类有一个InstanceContextMode属性它具有下列值值描述InstanceContextMode.PerCall当客户端调用服务的一个操作时该服务就创建一个新实例。当调用完成服务实例回收该实例。InstanceContextMode.PerSession如果服务实现了Session当session启动时创建一个新实例当Session结束时回收该实例。一个客户端能在session存活时间内多次调用该服务。但是每个服务实例只能访问一个session. 更多信息请参考第七章。InstanceContextMode.Single只创建一个服务的实例。该实例能被所有客户端和sessions共享。此实例在第一个客户端访问该服务时创建。默认的InstanceContextMode是PerCall。 你可以按照下列方式修改InstanceContextModeServiceBehavior Attribute请看下面三张图它们形象地说明了WCF运行时创建服务实例的三种模式注:图片来自http://www.codeproject.com/KB/WCF/WCFInstance.aspxWCF客户端程序能通过代理类与WCF服务进行通信。你可使用Visual Studio或svcuti.exe来生产代理类。代理类在客户端实现一个通道堆栈。你可以采用与服务端堆栈同样的方式配置客户端通道堆栈。所有服务端的响应将通过客户端通道堆栈。为了成功的通信客户端和服务端应采用对应的通道堆栈且绑定设置应相互兼容。WCF通道堆栈与TCP/IP栈。两者的共同点栈中的每一层均提供该层下面的一些抽象并仅向上的一层公开该抽象。而且在这两种情况下两个堆栈通信时每个层均与另一个堆栈中的相应层通信例如IP与IP层通信TCP层与TCP层通信以此类推。两者的不同点TCP堆栈旨在提供物理网络的抽样而通道堆栈不仅提供消息传送方式的抽象还提供其他功能比如消息的内容或通信所使用的协议的抽象。例如可靠的会话绑定元素是通道堆栈的一部分但却在不传输本身中。次抽象是通过要求堆栈中的底部通道是基础传输协议适应通道推展体系结构然后依赖堆栈中更上层的通道通信功能来实现的。WCF运行时架构请移步至idior的博客Inside WCF runtimehttp://www.cnblogs.com/idior/articles/971252.html2 使用WAS寄宿WCF服务在第一章中你已经学习到如何将一个WCF服务寄宿在IIS上。IIS提供了为Web服务提供了广泛的、可靠的宿主环境这意味着客户端程序通过互联网连接到该服务。Web服务使用HTTP协议进行通信传输。IIS侦听HTTP请求如果一个请求到达IIS激活对应的服务去处理该请求。虽然HTTP协议是一个非常适宜于通过互联网连接到Web服务的传输协议。但是当在企业内部创建一个供内部客户端访问的服务时应采用其他的协议。WAS通过移除对HTTP协议的依赖而扩展了IIS的功能。使用WAS你的寄宿服务可以采用其他的协议比如TCP命名管道和MSMQ。WAS能够侦听请求并激活一个采用其他协议并等待在对应地址上服务。到目前为止 我们所学习到的WCF服务在多数情况下都只仅仅关注配置文件中的传输协议和地址的详置信息。因为服务契约数据契约和服务的实现很大程序上独立于宿主环境和服务采用的传输协议。在下面的练习中你配置WAS使ProductService寄宿于其上该服务通过TCP接受请求。你将更新第一章创建的ProductClient程序使其能通过TCP协议连接到ProductService。准备工作安装和配置WAS。由于WAS在Windows 7上并没有默认安装和配置。你需要用管理员身份执行下列步骤Windows—开始菜单—控制面板—程序添加删除Windows特性选择Windows process activation service及其子项目并选择.net framework 3.5及其子项目。然后点击OK当安装完毕之后请检查IIS对应的ASP.NET的版本。如果不是4.0版本请在Visual Studio Command Prompt窗口中执行命令aspnet_regiis -iru1配置宿主环境使WCF服务支持TCP协议用管理员身份运行IIS管理工具在iis管理工具中选择编辑绑定站点绑定对话将将出现如果你成功安装了WAS那么将显示该网站的默认绑定协议。从下图中可以看到WAS所采用的net.tcp协议将默认监听808端口。如果你想修改该端口点击Edit按钮。在本章的例子中我们将使用默认的端口。关闭站点绑定对话框。展开站点选择ProductsService并选择高级设置对该服务添加tcp.net协议。关闭高级设置对话框。现在ProductsService的宿主环境被配置为使用HTTP和TCP协议侦听请求。2配置客户端应用程序使其能通过TCP协议连接WCF服务按照下面的文件接口复制第一章的ProductsClient项目由于我们已经在IIS上部署了ProductsService并且该服务使用HTTP和TCP协议因为我们需要在ProductsClient项目中更新服务引用的地址然后在弹出的对话框中输入地址然后点击OKVisual Studio将会自动更新。更新完毕后打开app.config文件你会发现在配置文件中多了一个endpoint和与之对应的banding信息。修改Progrom.cs更新proxy的定义。ProductsServcieClient proxy new ProductsServcieClient(NetTcpBinding_IProductsServcie);编译你的项目然后查看运行结果。你将会发现与第一章的结果完全一致区别只不过是采用ProductsClient使用TCP传输协议连接到ProductsService罢了。3 在应用程序中寄宿WCF服务除了IIS或WAS你还可以使用其他的方式寄宿WCF服务你可以创建一个Windows程序寄宿WCF服务用户使用它来启动和停止WCF服务你可以在Windows服务中寄宿WCF服务这样只要Windows运行你的服务也会一直运行你还可以在WF服务程序中寄宿WCF服务这其实是Windows程序寄宿WCF服务的扩展当然这种方式有其独有的定义和实现服务的方式。在本章的后续内容中你将会看到如何创建Windows应用程序和Windows服务来寄宿WCF服务。在第八章将学习如何使用WF来寄宿WCF服务。在我们开始练习前你应该了解ServiceHost类。1使用ServiceHost类到目前为止我们所创建的WCF宿主程序都能自动执行服务。如果你创建一个自己的程序而不使用IIS或者WAS你可以通过使用System.ServiceModel命名空间下的ServiceHost类来完成这样的任务。ServiceHost对象可以从包含服务类的组件中实例化一个服务对象通过绑定信息来配置服务的端点绑定信息可以功过配置文件或者代码方式进行设置设置服务所需的安全需求为你所指定的每个地址创建侦听对象。你通过指定服务实现类的类型创建一个ServiceHost对象。你可以按照下列方式指定ServiceHost侦听请求的地址:ServiceHost productsServiceHost new ServiceHost(typeof(ProductsService), new Uri[] { new Uri(http://localhost:8000/ProductsService/ProductsService.svc ), new Uri(tcp.net://localhost:8080/TcpProductsService ) });上述例子使用了在第一章中创建的ProductService服务。它使用了两个地址第一个采用HTTP传输第二个使用TCP。严格的来讲你在ServcieHost构造函数中指定的地址是基本地址。基本地址只是地址初始化的一部分。当你在配置文件中设置了更详细的地址信息那么这个详细的地址信息将和基本地址合并。比如ServiceHost在配置文件中你做了如下配置*.Config那么WCF运行时将会把这两个元素合并而生成一个地址http://localhost:8000/ProductsService/ ProductsService.svc。 这是一个非常有用的特性管理员可以在某个站点上使用这个特性引导一个服务使用一个特殊的地址。此特性还可以让开发人员对寄宿服务的站点拥有控制权。如果你在ServiceHost构造函数中没有指定地址参数那么WCF运行时将使用在配置文件中指定的地址信息并且在所有配置的端点上侦听请求。这将赋予管理员对该服务所使用的地址和传输拥有完整的控制权。为了方便在本章随后的练习中我们将尽可能地在配置文件中指定详细的地址信息。但是当创建企业应用是你可以通过编程方式为服务端点指定基本地址。