WCF 持久化服务






4.85/5 (8投票s)
WCF 持久化服务
引言
在这篇文章中,我将描述持久化服务及其在WCF中的实现。
如你所知,HTTP是一个无状态协议。因此,如果我们谈论web应用程序、web服务和WCF,所有这些技术都支持HTTP。这意味着它们是无状态的,或者无法在多个请求之间持久化服务器对象的状体。
在WCF中,持久化服务用于此目的,这意味着它提供了一种在多个请求之间持久化服务对象实例的方法。即使服务重启,持久化服务也会保留服务对象。
现在让我解释持久化服务是如何做到这一点的。
持久化服务将服务对象的实例序列化为XML,并使用GUID作为唯一键将此XML存储在数据库中。客户端将此GUID发送到服务,服务使用此GUID从数据库获取相应的实例来处理该请求。
我们还可以使用会话状态持久化(`InstanceContextMode.PerSession`)在WCF中持久化实例对象。唯一的区别是,会话状态持久化将保留实例,直到服务或客户端重启。由于会话状态持久化将实例存储在内存中,因此当客户端或服务器重启时,它将丢失该对象。但是,持久化服务将实例存储在数据库中,即使服务重启后,也可以使用提供的GUID从数据库获取实例。现在让我们看看在WCF中实现持久化服务的示例。
WCF持久化服务实现
A. 数据库设置
第一步是设置数据库以存储实例,SQL Server已经拥有创建表、模式、用于管理实例的存储过程所需的所有脚本。
- 创建一个数据库来存储SQL Server中序列化的实例,并将其命名为“`DurableServiceDB`”。
- 现在转到“`C:\Windows\Microsoft.NET\Framework\v3.5\SQL\EN`”位置,并从“`SqlPersistenceProviderSchema.sql`”和“`SqlPersistenceProviderLogic.sql`”文件中获取脚本。
`SqlPersistenceProviderSchema.sql`包含创建表和模式的脚本,`SqlPersistenceProviderLogic.sql`包含用于存储、检索和删除数据库中实例的存储过程的脚本。
- 现在为你的数据库执行以上两个脚本。
- 执行以下脚本
USE DurableServiceDB
- 现在执行`SqlPersistenceProviderSchema.sql`脚本
- 现在执行`SqlPersistenceProviderLogic.sql`脚本
- 执行以下脚本
接下来,我们将实现持久化服务。
B. 创建持久化服务
- 创建一个名为“`MergeStringService`”的WCF服务应用程序。
- 将`IServce1.cs`重命名为`ImergeStringDurableService.cs`,并将以下代码粘贴到文件中。
using System.ServiceModel; namespace MergeStringService { [ServiceContract] public interface IMergeStringDurableService { //To Persist the instance in db [OperationContract] void PersistServiceInstance(); [OperationContract] void MergeString(string str); [OperationContract] string GetMergedString(); //To Remove instance from db [OperationContract] void RemoveServiceInstance(); } }
- 将`Service1.svc`重命名为“`MergeStringDurableService`”,并更新代码。
<%@ ServiceHost Language="C#" Debug="true" Service="MergeStringService.MergeStringDurableService" CodeBehind="MergeStringDurableService.svc.cs" %>
- 在`MergeServiceDurableService.svc.cs`中添加以下代码。
using System; using System.ServiceModel.Description; namespace MergeStringService { [Serializable] [DurableService()] public class MergeStringDurableService : IMergeStringDurableService { private string mergedString; [DurableOperation(CanCreateInstance = true)] public void PersistServiceInstance() { //It will create and store the Instance in db } [DurableOperation()] public void MergeString(string str) { mergedString += str; } [DurableOperation()] public string GetMergedString() { return mergedString; } [DurableOperation(CompletesInstance = true)] public void RemoveServiceInstance() { //It will remove instance from DB } } }
这里`Serializable`属性用于类,因为它需要将实例序列化为XML才能存储在数据库中。它使用了两个新属性
- `DurableService`:此属性用于指定持久化服务的实现。
- `DurableOperation`:它指定持久化服务公开的函数。它允许指定两个属性
- `CanCreateInstance`:将此属性设置为`true`以将实例持久化到数据库中。
- `CompletesInstance`:将此属性设置为`true`以从数据库中删除实例。
- 更新`web.config`文件如下,并相应地编辑`connectionString`。
<?xml version="1.0"?> <configuration> <connectionStrings> <add name="StringServiceDB" connectionString="Data Source=MyMachine\SQLEXPRESS; Initial Catalog=StringServiceDB;Integrated Security=True"/> </connectionStrings> <system.serviceModel> <services> <service name="MergeStringService.MergeStringDurableService" behaviorConfiguration="DurableServiceBehavior"> <endpoint address="" binding="wsHttpContextBinding" bindingConfiguration="DurableServiceBindingConfig" contract="MergeStringService.IMergeStringDurableService"> <identity> <dns value="localhost"/> </identity> </endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="DurableServiceBehavior"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <persistenceProvider type="System.ServiceModel.Persistence.SqlPersistenceProviderFactory, System.WorkflowServices, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="StringServiceDB" persistenceOperationTimeout="00:00:10" lockTimeout="00:01:00" serializeAsText="true"/> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpContextBinding> <binding name="DurableServiceBindingConfig"> <security mode="None"/> </binding> </wsHttpContextBinding> </bindings> </system.serviceModel> <system.web> <compilation debug="true"/> </system.web> </configuration>
- 现在持久化服务的实现已经完成。我们的最后一步是创建一个客户端应用程序。
C. 创建客户端应用程序
- 创建一个名为“`DurableServiceClient`”的控制台应用程序,并运行服务应用程序。
- 添加服务引用并将其命名为“`StringOperationService`”。
- 现在将以下代码添加到`Program.cs`中。
using System; using DurableServiceClient.StringOperationService; namespace DurableServiceClient { class Program { static MergeStringDurableServiceClient serviceClient; static void Main(string[] args) { serviceClient = new MergeStringDurableServiceClient(); //Store the Instance in database serviceClient.PersistServiceInstance(); Console.WriteLine("Instance stored in Database as XML."); while (true) { Console.WriteLine("Want to clear Instance ? (Y/N)"); string selectedOption = Console.ReadLine(); if (selectedOption.ToUpper().Equals("Y")) { //To remove instance from database serviceClient.RemoveServiceInstance(); Console.WriteLine("Instance removed from database."); break; } else { Console.WriteLine("Please enter the string to merge: "); //Merge the string serviceClient.MergeString(Console.ReadLine()); //To display merged string Console.WriteLine("Merged String: {0}", serviceClient.GetMergedString()); } } Console.ReadLine(); } } }
- 现在运行客户端应用程序并输入一些`字符串`,看看合并后的`字符串`。现在停止服务应用程序并再次运行服务。转到客户端应用程序控制台并输入一些要合并的`字符串`。你会发现它将给出整个合并的`字符串`作为输出,这意味着它对这个请求使用了相同的服务实例。
- 现在执行查询
SELECT * FROM [DurableServiceDB].[dbo].[InstanceData]
它将显示存储在数据库中的实例。
- 现在要从数据库中删除服务实例,键入“`Y`”并按Enter键,它将从数据库中删除实例。
因此,即使在重启服务后,持久化服务也会保留实例。