WCF揭秘——可靠性会话功能

一、可靠性会话

Windows Communication Foundation (WCF) 可靠性会话是一个如 WS-ReliableMessaging 协议所定义的 SOAP 可靠消息传递的实现。它在绑定层保证消息只会被传送一次,并能确定消息之间的传输顺序。它的特性在于保证了传输过程中消息不会丢失或者错位,在连接掉线的 时候,它会重新连接服务器,连接次数可在配置文件中设定,当在连接失败的时候,能自动释放对话所占用的资源。

系统有多个绑定支持可靠性会话功能:wsHttpBinding、wsDualHttpBinding、wsFederationBinding、 netTcpBinding、netNamedPipesBinding。其中wsHttpBinding、wsFederationBinding、 netTcpBinding在默认情况下可靠性会话功能是关闭。而wsDualHttpBinding、netNamedPipesBinding则默认 支持可靠性功能。

二、开发实例

可靠性会话功能可以通过代码绑定,也可以通过config配置统一绑定,值得注意的是服务器端要与客户端的配置必须保持一致,避免出现冲突。下面以 netTcpBinding契约为例子,说明一下可靠性会话的功能。首先建立数据契约Person,和服务契约PersonService,客户端通过 GetPerson方法获取Person对象。

  • 服务器端
 
 
  1.  1 namespace Pro.Model 
  2.  2 { 
  3.  3     //建立数据契约 
  4.  4     [DataContract] 
  5.  5     public class Person 
  6.  6     { 
  7.  7         [DataMember] 
  8.  8         public int ID 
  9.  9         { 
  10. 10             get
  11. 11             set
  12. 12         } 
  13. 13  
  14. 14         [DataMember] 
  15. 15         public string Name 
  16. 16         { 
  17. 17             get
  18. 18             set
  19. 19         } 
  20. 20  
  21. 21         [DataMember] 
  22. 22         public int Age 
  23. 23         { 
  24. 24             get
  25. 25             set
  26. 26         } 
  27. 27     } 
  28. 28 } 
  29. 29  
  30. 30 namespace Pro.Service 
  31. 31 { 
  32. 32     // 建立服务契约接口“IPersonService”。 
  33. 33     [ServiceContract] 
  34. 34     public interface IPersonService 
  35. 35     { 
  36. 36         [OperationContract] 
  37. 37         Person GetPerson(); 
  38. 38     } 
  39. 39  
  40. 40     // 实现服务契约“PersonService”。 
  41. 41     [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 
  42. 42     public class PersonService : IPersonService 
  43. 43     { 
  44. 44         public Person GetPerson() 
  45. 45         { 
  46. 46             Person person = new Person(); 
  47. 47             person.ID = 0; 
  48. 48             person.Name = "Leslie"
  49. 49             person.Age = 31; 
  50. 50              
  51. 51             return person; 
  52. 52         } 
  53. 53     } 
  54. 54  
  55. 55     class Program 
  56. 56     { 
  57. 57         //启动服务 
  58. 58         static void Main(string[] args) 
  59. 59         { 
  60. 60             Console.WriteLine("Service star!"); 
  61. 61             ServiceHost host1 = new ServiceHost(typeof(PersonService)); 
  62. 62             host1.Open(); 
  63. 63             Console.ReadKey(); 
  64. 64             host1.Close(); 
  65. 65         } 
  66. 66     } 
  67. 67 } 

添加config配置文件,加入 reliableSession 配置,包含以下属性

1.enable 

返回值为bool类型,代表是否打开可靠性功能。

2.inactivityTimeout 

返回值为TimeSpan类型,代表闲置超时时间,默认值为10分钟,如果客户端已经建立起服务对象,在超过此时间内没有重新调用这些对象,系统将 发送提示信息: “通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于‘出错’状态。”。

3.ordered

返回值为bool类型,代表是否开启“有序性”性功能,如果开启此功能,代表消息将按顺序传送。

4.maxPendingChannels

返回值为int 类型,代表最大等候信道,默认值为4。

5.maxRetryCount

返回值为int 类型,表示最大重复发送次数,默认值为8,最大值为20。如果因断线等原因连接失败,客户端重试次数超过此最大值,系统将发出错误提示。

6.flowControlEnabled

返回值为bool类型,默认值为true,代表是否启动流量控制器。启动后,当接收方的传输数据缓冲区已满时,发送方将延迟发送信息。

7.acknowledgementInterval

返回值为TimeSpan类型,默认值为00:00:00.2(即0.2秒),代表接收方在接收信息之前所需要的等待时间。

8.maxTransferWindowSize

返回值为int类型,默认值为8,用于控制数据缓冲区数量。

 1 <configuration>
2 <system.serviceModel>
3 <behaviors>
4 <serviceBehaviors>
5 <behavior name="">
6 <serviceMetadata httpGetEnabled="false" />
7 <serviceDebug includeExceptionDetailInFaults="true" />
8 </behavior>
9 </serviceBehaviors>
10 </behaviors>
11
12 <bindings>
13 <netTcpBinding>
14 <binding name="defaultNetTcpBinding">
15 <!--打开可靠性会话功能,把过期时间配置为10秒-->
16 <reliableSession enabled="true" inactivityTimeout="00:00:10"/>
17 </binding>
18 </netTcpBinding>
19 </bindings>
20
21 <services>
22 <service name="Pro.Service.PersonService">
23 <!--绑定defaultNetTcpBinding-->
24 <endpoint address="" bindingConfiguration="defaultNetTcpBinding" binding="netTcpBinding" contract="Pro.Service.IPersonService">
25 <identity>
26 <dns value="localhost" />
27 </identity>
28 </endpoint>
29 <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
30 <host>
31 <baseAddresses>
32 <add baseAddress="net.Tcp://localhost:6000/Pro.Service/PersonService/" />
33 </baseAddresses>
34 </host>
35 </service>
36 </services>
37 </system.serviceModel>
38 </configuration>

在以上例子中,只在netTcpBincding绑定中加入了enable与inactivityTimeout两个最常用的功能,其意义只在于打 开可靠性会话功能,把超时时间设置为10秒(定制10秒的超时时间,其用意是在于测试在10秒后再次调用服务对象,对象是否会抛出错误提示)。

  • 客户端

新建一个网站项目,添加对PersonService服务的引用,在页面加入一个Label控件与一个Button控件,在Button的onClick方法调用PersonService服务。

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/C#" runat="server">
protected void btn1_Click(object sender, EventArgs e)
{
//注意在调用完成后把服务销毁
using (PersonService.PersonServiceClient personService = new PersonService.PersonServiceClient())
{
Pro.Model.Person person
= personService.GetPerson();
Label1.Text
= person.Name;
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:Button ID="btn1" runat="server" Text="Button" OnClick="btn1_Click"/>
</div>
</form>
</body>
</html>

配置客户端文件,打开可靠性会话功能,注意把超时时间设置为10秒,与服务器的配置同步。在常用的服务处理页面,使用单体模式或者静态对象,在一定 程序上可以减少服务器的负荷,提高效率。值得注意的是,如果使用单体模式,当服务启动10秒后,如果并未被再次调用,那下次调用时,系统将显示错误信息: “通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于‘出错’状态”。所以,在配置“超时时间”时,应该注意控制时间的长短。

为了避免出现以上错误,在下建议在调用不经常使用的服务之时,应该把服务对象及时销毁,下次调用时重新建立一个服务对象。(可参考“注意事项”)

 1 <configuration>
2 <system.web>
3 <compilation debug="true" targetFramework="4.0"/>
4 </system.web>
5 <system.serviceModel>
6 <bindings>
7 <netTcpBinding>
8 <binding name="NetTcpBinding_IPersonService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout
="00:01:00" transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode
="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288" maxBufferSize="65536"
maxConnections
="10" maxReceivedMessageSize="65536">
9 <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
10 <!--启动可靠性会话,把过期时间设置为10秒-->
11 <reliableSession inactivityTimeout="00:00:10" enabled="true"/>
12 <security mode="Transport">
13 <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
14 <message clientCredentialType="Windows"/>
15 </security>
16 </binding>
17 </netTcpBinding>
18 </bindings>
19 <client>
20 <endpoint address="net.tcp://localhost:6000/Pro.Service/PersonService/" binding="netTcpBinding"
bindingConfiguration
="NetTcpBinding_IPersonService" contract="PersonService.IPersonService" name="NetTcpBinding_IPersonService">
21 <identity>
22 <dns value="localhost"/>
23 </identity>
24 </endpoint>
25 </client>
26 </system.serviceModel>
27 </configuration>

三、注意事项

值得注意的一点是,在某些不常用到的页面中(比如在Login登录页面),客户往往在长时间内只调用一次服务,所以应该注意对服务对象进行及时销毁,否则客户再次登录时就会出来错误。

 1 <html xmlns="http://www.w3.org/1999/xhtml">
2 <head runat="server">
3 <title></title>
4 <script type="text/C#" runat="server">
5 static PersonService.PersonServiceClient personService = new PersonService.PersonServiceClient();
6 //只在页面初次调用时,personService才会被新建,如果超过限时没有被再次调用,就会出现错误
7
8 protected void btn1_Click(object sender, EventArgs e)
9 {
10 Pro.Model.Person person = personService.GetPerson();
11 Label1.Text = person.Name;
12 }
13 </script>
14 </head>
15 <body>
16 <form id="form1" runat="server">
17 <div>
18 <asp:Label ID="Label1" runat="server"></asp:Label>
19 <asp:Button ID="btn1" runat="server" Text="Button" OnClick="btn1_Click"/>
20 </div>
21 </form>
22 </body>
23 </html>

相关文章

简单的WCF开发实例

使用AJAX+WCF进行页面开发

共享数据契约

可靠性会话功能

对JAVA与.NET开发有兴趣的朋友欢迎加入QQ群:162338858 点击这里加入此群



本文转自 leslies2  51CTO博客,原文链接:http://blog.51cto.com/79100812/634310

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值