WCF SOAP 可靠消息传递提供 SOAP 终结点之间的端对端消息传输可靠性。此消息传递通过克服传输失败和 SOAP 消息级别失败,可在不可靠的网络上实现传输可靠性。具体而言,它为跨 SOAP 或传输中介发送的消息提供了一种基于会话的、单一的和(可选)有序的传送。基于对话的传送可按消息的顺序(可选)将消息分组到一个会话中。
简单的说可靠会话就是保证:
- 消息不会丢失
- 消息不会重复
- 接收的顺序与发送顺序一致
要使用 WCF 可靠会话,使用支持可靠会话的绑定创建一个终结点即可。默认情况下WSDualHttpBinding支持并启用可靠会话的系统定义的绑定。支持可靠会话但默认情况下不启用的系统提供的绑定包括:WSHttpBinding、WSFederationHttpBinding、NetTcpBinding。通过设置绑定的ReliableSessionBindingElement开启可靠会话,在配置文件中设置如下面所示:
<bindings> <wsHttpBinding> <binding name="Binding1"> <reliableSession enabled="true" /> </binding> </wsHttpBinding> </bindings> <endpoint address="" binding="wsHttpBinding" bindingConfiguration="Binding1" contract="Microsoft.ServiceModel.Samples.ICalculator" />
在代码中使用:
Uri baseAddress = new Uri("http://localhost:8000/servicemodelsamples/service"); // Create a ServiceHost for the CalculatorService type and provide the base address. using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress)) { // Create a custom binding that contains two binding elements. ReliableSessionBindingElement reliableSession = new ReliableSessionBindingElement(); reliableSession.Ordered = true; HttpTransportBindingElement httpTransport = new HttpTransportBindingElement(); httpTransport.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous; httpTransport.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; CustomBinding binding = new CustomBinding(reliableSession, httpTransport); // Add an endpoint using that binding. serviceHost.AddServiceEndpoint(typeof(ICalculator), binding, ""); // Add a MEX endpoint. ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; smb.HttpGetUrl = new Uri("http://localhost:8001/servicemodelsamples"); serviceHost.Description.Behaviors.Add(smb); // Open the ServiceHostBase to create listeners and start listening for messages. serviceHost.Open(); // The service can now be accessed. Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); // Close the ServiceHostBase to shutdown the service. serviceHost.Close(); }
ReliableSessionBindingElement各个属性的含义:
- AcknowledgementInterval:表示消息接收端发送确认之前等待的时间间隔,默认为0.2秒(200毫秒),该设置仅针对于NetTcpBingding和WSDualHttpBiding等支持双工通信的绑定有效。如果是双工通信,接收方能够随时向接收方发送确认,为了降低网络流量,WCF采用批量确认的机制。它不会一收到消息就尽快发送该消息的确认,而是会等待一段时间,将该间隔期间内到达的确认组合在一起,然后一并发送。如果收到的第一条消息是异常消息,则会在消息传出后立即进行确认。
- FlowControlEnabled:该属性指示会话是否已启用流控制(Flow Control)。流控制是可靠会话实现的一种机制,目的是确保发送方所发送的消息数不超过接收方可处理的消息数。接收方拥有消息缓冲区,用于容纳突增的消息和无序的消息。接收方在每次确认时都会告知发送方此缓冲区中的剩余空间量。利用此信息,发送方就可以在接收方缓冲区中没有剩余空间时,停止发送新的消息。FlowControlEnabled默认值为True。
- InactivityTimeout:服务在关闭之前保持非活动状态的时间间隔。在WS-RM中,被创建的RM序列具有一个Expires属性表示序列的生命周期。但是,我们不能通过可靠会话的整个生命周期的时限,也就是,整个可靠会话并没有具体时间的限制。但是,WCF并不能依赖于可靠会话被显式地被终止,而设定一个超时时限,在该时间范围内如何没有活动的消息交换,WCF会将可靠会话关闭。InactivityTimeout就是这么一个表示可靠会话在关闭之前保持非活动状态的时间间隔,默认值为10分钟。
- MaxPendingChannels:在可靠会话期间可为挂起状态的最大通道数。通道在等待被接受时处于挂起状态。一旦达到该限制,就不会创建任何通 道并将其置于挂起模式,直到此数值降低(通过接受挂起的通道)。这是对每个侦听器的限制。当达到此阈值时如果远程应用程序尝试建立新的可靠会话,则会拒绝请求且打开操作将提示此错误。默认值为4。
- MaxRetryCount:在会话期间尝试传输消息的最大次数。如果在某个可接受时间范围内,消息的发送端没有接收到某个已发消息的确认,会对该消息进行重传。MaxRetryCount表示重传的次数,默认值为8。在达到此限制之前未接收到确认被视为严重的通信故障,这种情况将引发通道出错的事件。
- MaxTransferWindowSize:在发送缓冲区或接收缓冲区中可存在的最大消息数。MaxTransferWindowSize最小值为1,最大值为4096,默认值为32。MaxTransferWindowSize属性的值可在发送方和接收方进行设置。如果发送方达到这个限制,则会阻止其他发送调用。如果接收方达到这个限制,则不会接受到达基础通道的新消息。可靠会话会使用windowing protocol来帮助提高网络利用率。所需的缓冲量直接从传输窗口的大小派生而来。调整此值时请注意,最佳传输窗口直接与带宽和延迟相关。理想的最大窗口大小是带宽乘以延迟。如果比此值小,网络利用率就会低于 100%,如果比此值大,就会浪费空间。
- Ordered:该属性表示是否启用“有序传输”机制确保消息的接收端完全按照消息被发送的顺序进行交付;默认值为False。若要按顺序调度消息,还必须将 ConcurrencyMode 设置为 Single。
- ReliableMessagingVersion:该属性表示可靠会话支持的WS-RM的版本。
可靠会话的最佳做法:http://msdn.microsoft.com/zh-cn/library/ms733795(v=vs.100).aspx