使命必达: 深入剖析WCF的可靠会话[编程篇](下)

整个可靠会话的机制是完全在信道层实现的,而整个信道层的最终缔造者就是绑定,所以可靠会话编程是围绕着绑定进行的。《上篇》对实现可靠会话的绑定元素已经如何使用系统绑定实现可靠会话进行了介绍,下篇将和你探讨WCF可靠会话编程模型余下两个主题:自定义绑定对消息传递的强制约束

一、为自定义绑定的可靠会话进行设置

绑定是一系列绑定元素的有序组合,但是系统绑定为我们提供适应了某种典型通信环境的绑定元素组合方式,可以看成是“套餐”。但是,如果套餐不符合您的胃口,你应该查看菜单点你喜欢的菜肴。自定义绑定给了你最大的自由度,是能能够根据具体的通信环境自由组合需要的绑定元素。

关于可靠会话,如果你采用系统绑定,你定制的范围其实很窄(仅限于InactivityTimeout和Ordered属性)。但是,如果你采用自定义绑定,由于你操作的对象就是ReliableSessionBindingElement绑定元素,所有你可以对所有的选项进行自由配置。虽然我们可以通过编程的方式之间将创建的ReliableSessionBindingElement对象添加到绑定的绑定元素集合中,但是我们还是强烈建议你通过配置的方式来对可靠会话的相关选项进行定制。为了让读者能够了解某个特性的配置,我个人觉得最好的办法就是直接让读者看看相关配置节的定义。WCF将ReliableSessionBindingElement的配置定义在如下所示的ReliableSessionElement类型中。通过ReliableSessionElement,你不但可以了解可靠会话相关的配置属性,还可以了解到其他相关的配置信息,比如最大值、最小值和默认值等。你可以验证一下它们是否和我们前面的介绍一致。

   1: public sealed class ReliableSessionElement : BindingElementExtensionElement
   2: {
   3:    [ConfigurationProperty("acknowledgementInterval", DefaultValue="00:00:00.2"), TypeConverter(typeof(TimeSpanOrInfiniteConverter)), ServiceModelTimeSpanValidator(MinValueString="00:00:00.0000001")]
   4:     public TimeSpan AcknowledgementInterval { get; set; }
   5:     public override Type BindingElementType { get; }
   6:     [ConfigurationProperty("flowControlEnabled", DefaultValue=true)]
   7:     public bool FlowControlEnabled { get; set; }
   8:     [ServiceModelTimeSpanValidator(MinValueString="00:00:00.0000001"), TypeConverter(typeof(TimeSpanOrInfiniteConverter)), ConfigurationProperty("inactivityTimeout", DefaultValue="00:10:00")]
   9:     public TimeSpan InactivityTimeout { get; set; }
  10:     [IntegerValidator(MinValue=1, MaxValue=0x4000), ConfigurationProperty("maxPendingChannels", DefaultValue=4)]
  11:     public int MaxPendingChannels { get; set; }
  12:     [IntegerValidator(MinValue=1), ConfigurationProperty("maxRetryCount", DefaultValue=8)]
  13:     public int MaxRetryCount { get; set; }
  14:     [ConfigurationProperty("maxTransferWindowSize", DefaultValue=8), IntegerValidator(MinValue=1, MaxValue=0x1000)]
  15:     public int MaxTransferWindowSize { get; set; }
  16:     [ConfigurationProperty("ordered", DefaultValue=true)]
  17:     public bool Ordered { get; set; }
  18:     protected override ConfigurationPropertyCollection Properties { get; }
  19:     [TypeConverter(typeof(ReliableMessagingVersionConverter)), ConfigurationProperty("reliableMessagingVersion", DefaultValue="WSReliableMessagingFebruary2005")]
  20:     public ReliableMessagingVersion ReliableMessagingVersion { get; set; }
  21: }

在对自定义绑定进行配置的时候,我们只需要在绑定元素集合中添加ReliableSessionElement配置元素,并对相应的配置属性进行设置即可。下面的XML是服务端的WCF配置,我们采用自定义绑定作为终结点绑定。该自定义绑定由三个绑定元素组成,通过TextMessageEncodingElement对消息进行基于文本编码;通过HttpTransportBindingElement采用HTTP协议进行传输;在两者之间的ReliableSessionBindingElement实现了对消息的可靠传输。在bindings/binding/reliableSession配置节中,我对所有的属性进行的显式设置。

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <configuration> 
   3:   <system.serviceModel>    
   4:     <bindings>
   5:       <customBinding>
   6:         <binding name="reliableSessionBinding">
   7:           <textMessageEncoding />
   8:           <reliableSession acknowledgementInterval="00:00:02" flowControlEnabled="false" inactivityTimeout="00:20:00" maxPendingChannels="8" maxRetryCount="4" maxTransferWindowSize="16" reliableMessagingVersion="WSReliableMessaging11" />
   9:           <httpTransport />
  10:         </binding>
  11:       </customBinding>     
  12:     </bindings>
  13:     <services>
  14:       <service name="Artech.MessageInspection.Receiver.CalculatorService">
  15:         <endpoint address="http://www.artech.com/calculatorservice"
  16:             binding="customBinding" bindingConfiguration="reliableSessionBinding"
  17:             contract="Artech.MessageInspection.Receiver.ICalculator" />
  18:       </service>
  19:     </services>
  20:   </system.serviceModel>
  21: </configuration>

看到这里,我想有的读者会问这么一个问题:一个绑定可以有一系列绑定元素构成,那么ReliableSessionBindingElement应该置于何处呢?要搞清楚这个问题,需要对WCF的绑定模型有一个大致的了解。绑定的目的创建一个用于处理和传输消息的信道栈,信道在信道栈的顺序决定于对应的绑定元素的排列顺序。可靠会话将客户端和服务端通过ReliableSessionBindingElement创建的可靠信道作为分界线,并在它们之间提供消息可靠传输保障。也就是说,信道栈中位于可靠信道之下(靠近传输信道)部分存在于可靠会话的势力范围之中,而上面部分则脱离可靠会话的管辖范围。这也是在前面给出的实例中为何我们将用于模拟不可靠网络的绑定元素配置到ReliableSessionBindingElement之下的原因所在。

由于在实际的应用中,我们主要通过可靠会话为网络传输的不稳定性提供可靠传输的保障,所以我们一般将ReliableSessionBindingElement配置到传输绑定元素之上。至于消息编码绑定元素,是置于ReliableSessionBindingElement之上或者之下均没有关系。如果你认真阅读过《WCF技术剖析(卷1)》第3章,你会知道消息编码绑定元素并不参与信道的创建,而是将编码的方式传入绑定上下文,传输信道据此采用相应的编码方式进行消息的编码或者解码。此外,为了,保证可靠会话的安全性,我们需要将可靠会话绑定到一个通过安全会话信道提供的安全上下文中。在这种情况下,ReliableSessionBindingElement需要位于安全绑定元素之上。

我们说WCF可靠会话编程完全就是围绕着绑定进行的,可以说得更加具体点,是围绕着ReliableSessionBindingElement进行的。除了对系统绑定或者自定义绑定进行设置,关于可靠会话编程模型,还涉及到一个契约行为:DeliveryRequirementsAttribute,我们可以利用DeliveryRequirementsAttribute对服务契约进行一些基于可靠会话的强制性约束。

二、通过DeliveryRequirementsAttribute对可靠会话进行强制约束

DeliveryRequirementsAttribute这个自定义特性,实际上是一个契约行为。我们可以将其应用到服务契约类型或者服务类型上,强制要求相应终结点绑定必须满足设定的关于消息传输方面的要求。DeliveryRequirementsAttribute定义如下,其中忽略了实现IContractBehavior接口的4个方法。

   1: [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple=true)]
   2: public sealed class DeliveryRequirementsAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
   3: {
   4:     //其他成员
   5:     public QueuedDeliveryRequirementsMode QueuedDeliveryRequirements { get; set; }
   6:     public bool RequireOrderedDelivery { get; set; }
   7:     public Type TargetContract { get; set; }
   8: }

DeliveryRequirementsAttribute定义了两个属性QueuedDeliveryRequirements和RequireOrderedDelivery,分别代表相应的终结点绑定必须满足的两个要求:队列传递和有序交付。队列传递及采用消息队列(即MSMQ)的机制进行消息传递,在下一个系列中我们会对队列服务进行单独介绍。而有序交付就是本章涉及的可靠消息传输的有序交付。IContractBehavior属性是对IContractBehaviorAttribute的实现,当我们将DeliveryRequirementsAttribute特性应用到某个实现了多个服务契约的服务上时,可以指定设置的消息传递要求是针对某个服务契约。

在服务端,当基于服务类型创建的ServiceHost对象被开启的时候,如果相应终结点绑定无法满足通过将DeliveryRequirementsAttribute特性应用到服务契约类型或者服务类型上设置的关于队列传输或者有序交付的要求时,会抛出一个InvalidOperationException异常。如果将DeliveryRequirementsAttribute特性应用到服务契约上,客户端在试图开启ChannelFactory<TChannel>对象的时候,同样会验证用于服务调用的终结点绑定是否满足相应的要求,如果无法满足,同样会抛出一个InvalidOperationException异常。

举个例子,假设我们定义如下一个IOrderService的服务契约用于处理订单。在IOrderService接口上,应用了DeliveryRequirementsAttribute特性并将RequireOrderedDelivery设置成True,要求终结点绑定强制开启可靠消息的有序交付特性。

   1: [ServiceContract(Namespace = "http://www.artech.com/")]
   2: [DeliveryRequirements(RequireOrderedDelivery = true)]
   3: public interface IOrderService
   4: {
   5:     [OperationContract]
   6:     void Process(Order order);
   7: }

现在我们对实现该服务契约的服务进行寄宿,相应的配置如下。从中我们可以看到,我们采用WS2007HttpBinding作为终结点的绑定。通过绑定配置,开启了可靠会话,但是将ordered属性配置成False。

   1: ?xml version="1.0" encoding="utf-8" ?>
   2: <configuration>
   3:   <system.serviceModel>   
   4:     <bindings>      
   5:       <ws2007HttpBinding>
   6:         <binding name="reliableSessionHttpBinding">
   7:           <reliableSession ordered="false" enabled="true" />
   8:          </binding>
   9:       </ws2007HttpBinding>
  10:     </bindings>
  11:     <services>
  12:       <service name="Artech.MessageInspection.Receiver.OrderService">
  13:         <endpoint address="http://127.0.0.1:3721/OrderService" binding="ws2007HttpBinding"
  14:           bindingConfiguration="reliableSessionHttpBinding" contract="Artech.MessageInspection.Receiver.IOrderService" />
  15:       </service>
  16:     </services>
  17:   </system.serviceModel>
  18: </configuration>

当进行服务寄宿的时候,你会得到如图1所示的InvalidOperationException异常。当你进一步看清具体的异常消息的时候,你可能第一感觉就是作者把图片弄错了。因为终结点绑定部满足DeliveryRequirementsAttribute设定的关于有序交付的要求,和队列传递根据就不相关。但是图1就是真实运行后的截图,这是WCF自身的一个Bug。在《WCF 中关于可靠会话的BUG!!》这篇文章中有对该Bug的原因的深入探讨。

clip_image002

图1 终结点绑定不能满足DeliveryRequirementsAttribute设定的要求导致的异常

到此为止,关于WCF可靠会话编程方面的内容就到此为止,下一篇我们对可靠会话架构体系进行进一步的挖掘,对可靠会话具体的实现原理进行深入剖析,敬请期待。

作者: Artech
出处: http://artech.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
以下是对提供的参考资料的总结,按照要求结构化多个要点分条输出: 4G/5G无线网络优化与网规案例分析: NSA站点下终端掉4G问题:部分用户反馈NSA终端频繁掉4G,主要因终端主动发起SCGfail导致。分析显示,在信号较好的环境下,终端可能因节能、过热保护等原因主动释放连接。解决方案建议终端侧进行分析处理,尝试关闭节电开关等。 RSSI算法识别天馈遮挡:通过计算RSSI平均值及差值识别天馈遮挡,差值大于3dB则认定有遮挡。不同设备分组规则不同,如64T和32T。此方法可有效帮助现场人员识别因环境变化引起的网络问题。 5G 160M组网小区CA不生效:某5G站点开启100M+60M CA功能后,测试发现UE无法正常使用CA功能。问题原因在于CA频点集标识配置错误,修正后测试正常。 5G网络优化与策略: CCE映射方式优化:针对诺基亚站点覆盖农村区域,通过优化CCE资源映射方式(交织、非交织),提升RRC连接建立成功率和无线接通率。非交织方式相比交织方式有显著提升。 5G AAU两扇区组网:与三扇区组网相比,AAU两扇区组网在RSRP、SINR、下载速率和上传速率上表现不同,需根据具体场景选择适合的组网方式。 5G语音解决方案:包括沿用4G语音解决方案、EPS Fallback方案和VoNR方案。不同方案适用于不同的5G组网策略,如NSA和SA,并影响语音连续性和网络覆盖。 4G网络优化与资源利用: 4G室分设备利旧:面对4G网络投资压减与资源需求矛盾,提出利旧多维度调优策略,包括资源整合、统筹调配既有资源,以满足新增需求和提质增效。 宏站RRU设备1托N射灯:针对5G深度覆盖需求,研究使用宏站AAU结合1托N射灯方案,快速便捷地开通5G站点,提升深度覆盖能力。 基站与流程管理: 爱立信LTE基站邻区添加流程:未提供具体内容,但通常涉及邻区规划、参数配置、测试验证等步骤,以确保基站间顺畅切换和覆盖连续性。 网络规划与策略: 新高铁跨海大桥覆盖方案试点:虽未提供详细内容,但可推测涉及高铁跨海大桥区域的4G/5G网络覆盖规划,需考虑信号穿透、移动性管理、网络容量等因素。 总结: 提供的参考资料涵盖了4G/5G无线网络优化、网规案例分析、网络优化策略、资源利用、基站管理等多个方面。 通过具体案例分析,展示了无线网络优化中的常见问题及解决方案,如NSA终端掉4G、RSSI识别天馈遮挡、CA不生效等。 强调了5G网络优化与策略的重要性,包括CCE映射方式优化、5G语音解决方案、AAU扇区组网选择等。 提出了4G网络优化与资源利用的策略,如室分设备利旧、宏站RRU设备1托N射灯等。 基站与流程管理方面,提到了爱立信LTE基站邻区添加流程,但未给出具体细节。 新高铁跨海大桥覆盖方案试点展示了特殊场景下的网络规划需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值