WCF中的可信赖会话
如果需要保证消息的传输正确性,以及传输的消息顺序,在WCF中的实现非常容易,即使用可信赖会话ReliableSession,前提是我们应该选择正确的绑定。支持可信赖会话的绑定包括WSHttpBinding,WSDualHttpBinding,WSFederationBinding以及NetTcpBinding和NetNamedPipesBinding(该绑定使用IPC协议,按照Juval Lowy的说法,该绑定的类名并不合理。绑定的类名通常根据协议命名,而不是根据它所采用的技术,例如NetTcpBinding而不是NetSocketBinding。因此IPC绑定应命名为NetIPCBinding,而不是NetNamedPipesBinding)。其中,与WS-*相关的绑定需要手动打开可信赖会话。
由于绑定可以采用配置方式设定,因此,是否增加可信赖传输与具体的服务契约代码无关。此外,绑定的选择同样可以通过配置文件修改,这就保证了WCF实现的灵活性。配置可信赖会话的方式如下所示:
<binding name= "reliableBinding" receiveTimeout= "00:20:00">
<reliableSession enabled= "true" ordered= "true" inactivityTimeout= "00:20:00"/>
</binding>
</wsHttpBinding>
在配置文件中,让人疑惑不解的是两个超时值的设置。两者代表了不同的含义。receiveTimeout与应用程序消息相关,而inactivityTimeout则与应用程序以及基础架构消息相关。举例来说,如果一个服务契约包含了三个服务操作,且这三个操作将形成一个有序的序列(传输的消息顺序与此相关),那么计算非活动状态的值,对于前者而言是从调用服务对象的某一个操作之后开始计算,而后者则针对整个序列的操作。根据MSDN的解释,基础架构消息是指为了通道堆栈中的协议之一(例如,保持活动状态或确认,而并非包含应用程序数据)而生成的消息。
在可信赖会话中,任何一个超时值计时器触发都会断开连接,因此单独改变其中某一个的值是没有意义的。如果值不相同,则取两个值之间的最小值。他们的默认值均为10秒。
ReliableSession的Ordered属性保证了消息的传输顺序。它不意味着我们在调用服务对象时,必须遵循操作调用的顺序,而是指消息在发送时,必须按照调用的顺序传送。例如一个服务契约定义了M1,M2,M3三个服务操作。如果服务对象的调用顺序如下所示:
m_proxy.M2();
m_proxy.M3();
则消息的顺序为M1-> M2 -> M3。如果修改操作的调用顺序如下:
m_proxy.M2();
m_proxy.M1();
则消息的顺序为M3-> M2 -> M1。因此,我们应注意它与所谓的“分步操作(Demarcating Operation)”的区别。分步操作通过在[OperationContract]中指定IsInitiating和IsTerminating的值,标示操作的调用顺序。在DevX的一篇文章中有如下的服务契约定义:
public interface IChopstickBuilder
{
[OperationContract]
int GetChopsticksUnderConstruction();
[OperationContract]
void WarmupChopstickMachine();
[OperationContract]
void ConstructAChopstick();
}
其中要求WarmupChopstickMachine()必须在ConstructAChopstick()操作之前调用。为保证客户端调用不出现顺序的错误,单单启动可信赖会话的有序传递仍嫌不足。此时,我们可以为WarmupChopstickMachine()操作定义分步操作:
void WarmupChopstickMachine();
不过,这样的操作定义实际上是无效的,因为IsInitiating的默认值本身就是true,这样的设置与不设置的效果完全一致。因此,我们可以考虑对ConstructAChopstick()和GetChopsticksUnderConstruction()进行设置:
public interface IChopstickBuilder
{
[OperationContract(IsInitiating = false, IsTerminating = true)]
int GetChopsticksUnderConstruction();
[OperationContract]
void WarmupChopstickMachine();
[OperationContract(IsInitiating = false)]
void ConstructAChopstick();
}
使用分步操作需要会话的支持,因此需要在服务契约上将SessionMode设置为Required,否则会抛出InvalidOperationException异常。
对于某些严格要求可信赖会话的服务,为避免配置文件中错误设置可信赖会话的可能,可以强制要求WCF检查包含该服务契约的终结点,确认它是否选择了支持可信赖会话的绑定,并支持有序传递:
[DeliveryRequirements(RequireOrderedDelivery = true)]
public interface MyReliableService...

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
2014 jack对性能优化的记录
jack对性能优化一点看法 1.对于数据库而言,我觉得数据库安全和稳定是第一,性能优化第二 2.导致数据库性能因素:软件设计:利用中间件,减少并发产生的问题。软件代码的编写(SQL本身,SQL没有绑定变量 (硬解析)绑定变量有利于OLTP,而不是OLAP)。数据库设计:OLTP--内存--变量绑定OLAP--SQL优化,分区 硬件设计:CPU I/O负载情况,硬盘容量 3.锁与阻塞(latch),锁与阻塞是不同概念 4.除了锁与阻塞问题,首先我们应该看执行计划:访问数据方式是索引还是全表扫描,是hashjoin还是nestedloops join等。得到执行计划方式:explainplanforsetautotraceon第三方软件提供的GUI工具,常见TOAD, PL/SQLDeveloer 5.变量绑定(OLTP) SQL解析过程:(软解析)首先产生一个HASH函数运算,得到一个Hash值,然后到共享池寻找是否有匹配的SQL. (硬解析)如果有匹配的,直接执行当前SQL。如果没有。语法分析----语义分析----生成执行计划----SQL的执行。 绑定变量:本质就是讲oracle硬...
-
下一篇
Python的线程与进程
看过《Python分布式计算》,觉得线程和进程,最大的区别还是在于 —— 二者是如何与内存交互的。线程是共享式的内存架构,进程是分布式的内存架构,这才是问题的本质。下面是网上搜来的一些常规总结。 一、定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源. 二、关系 一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行. 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。 三、区别 进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的...
相关文章
文章评论
共有0条评论来说两句吧...